Skip to content
Snippets Groups Projects
Commit 7a636318 authored by Hahn, Steven's avatar Hahn, Steven
Browse files

Use compare_exchange_weak instead of a critical section.

parent 07dbbf82
No related branches found
No related tags found
No related merge requests found
...@@ -363,6 +363,16 @@ void MDNormSCD::cacheDimensionXValues() { ...@@ -363,6 +363,16 @@ void MDNormSCD::cacheDimensionXValues() {
} }
} }
namespace {
template <typename T, typename BinaryOp>
void AtomicOp(std::atomic<T> &f, T d, BinaryOp _Op) {
T old = f.load();
T desired = _Op(old, d);
while (!f.compare_exchange_weak(old, desired))
desired = _Op(old, d);
}
} // namespace
/** /**
* Computed the normalization for the input workspace. Results are stored in * Computed the normalization for the input workspace. Results are stored in
* m_normWS * m_normWS
...@@ -402,6 +412,8 @@ void MDNormSCD::calculateNormalization( ...@@ -402,6 +412,8 @@ void MDNormSCD::calculateNormalization(
const detid2index_map solidAngDetToIdx = const detid2index_map solidAngDetToIdx =
solidAngleWS->getDetectorIDToWorkspaceIndexMap(); solidAngleWS->getDetectorIDToWorkspaceIndexMap();
std::vector<std::atomic<signal_t>> signalArray(m_normWS->getNPoints());
auto prog = make_unique<API::Progress>(this, 0.3, 1.0, ndets); auto prog = make_unique<API::Progress>(this, 0.3, 1.0, ndets);
PARALLEL_FOR_IF(Kernel::threadSafe(*integrFlux)) PARALLEL_FOR_IF(Kernel::threadSafe(*integrFlux))
for (int64_t i = 0; i < ndets; i++) { for (int64_t i = 0; i < ndets; i++) {
...@@ -474,18 +486,16 @@ void MDNormSCD::calculateNormalization( ...@@ -474,18 +486,16 @@ void MDNormSCD::calculateNormalization(
// index of the current intersection // index of the current intersection
size_t k = static_cast<size_t>(std::distance(intersectionsBegin, it)); size_t k = static_cast<size_t>(std::distance(intersectionsBegin, it));
// signal = integral between two consecutive intersections // signal = integral between two consecutive intersections
double signal = (yValues[k] - yValues[k - 1]) * solid; signal_t signal = (yValues[k] - yValues[k - 1]) * solid;
AtomicOp(signalArray[linIndex], signal, std::plus<signal_t>());
PARALLEL_CRITICAL(updateMD) {
signal += m_normWS->getSignalAt(linIndex);
m_normWS->setSignalAt(linIndex, signal);
}
} }
prog->report(); prog->report();
PARALLEL_END_INTERUPT_REGION PARALLEL_END_INTERUPT_REGION
} }
PARALLEL_CHECK_INTERUPT_REGION PARALLEL_CHECK_INTERUPT_REGION
std::copy(signalArray.cbegin(), signalArray.cend(),
m_normWS->getSignalArray());
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment