From 7a6363189efb1872e577f8ba3eafa47d1bc32253 Mon Sep 17 00:00:00 2001 From: Steven Hahn <hahnse@ornl.gov> Date: Thu, 27 Apr 2017 16:38:13 -0400 Subject: [PATCH] Use compare_exchange_weak instead of a critical section. --- Framework/MDAlgorithms/src/MDNormSCD.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp index 866d15d23ab..ed8155a2690 100644 --- a/Framework/MDAlgorithms/src/MDNormSCD.cpp +++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp @@ -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 * m_normWS @@ -402,6 +412,8 @@ void MDNormSCD::calculateNormalization( const detid2index_map solidAngDetToIdx = solidAngleWS->getDetectorIDToWorkspaceIndexMap(); + std::vector<std::atomic<signal_t>> signalArray(m_normWS->getNPoints()); + auto prog = make_unique<API::Progress>(this, 0.3, 1.0, ndets); PARALLEL_FOR_IF(Kernel::threadSafe(*integrFlux)) for (int64_t i = 0; i < ndets; i++) { @@ -474,18 +486,16 @@ void MDNormSCD::calculateNormalization( // index of the current intersection size_t k = static_cast<size_t>(std::distance(intersectionsBegin, it)); // signal = integral between two consecutive intersections - double signal = (yValues[k] - yValues[k - 1]) * solid; - - PARALLEL_CRITICAL(updateMD) { - signal += m_normWS->getSignalAt(linIndex); - m_normWS->setSignalAt(linIndex, signal); - } + signal_t signal = (yValues[k] - yValues[k - 1]) * solid; + AtomicOp(signalArray[linIndex], signal, std::plus<signal_t>()); } prog->report(); PARALLEL_END_INTERUPT_REGION } PARALLEL_CHECK_INTERUPT_REGION + std::copy(signalArray.cbegin(), signalArray.cend(), + m_normWS->getSignalArray()); } /** -- GitLab