3232
3333#include " MantidTypes/SpectrumDefinition.h"
3434
35- #include " MantidAPI/AlgoTimeRegister.h"
36-
3735#include < boost/algorithm/string/join.hpp>
3836#include < boost/algorithm/string/regex.hpp>
3937
@@ -1114,15 +1112,9 @@ bool MatrixWorkspace::isHistogramDataByIndex(const std::size_t index) const {
11141112}
11151113
11161114bool MatrixWorkspace::setCommonBinsFlag (const bool value) const {
1117- // check valid flag before acquiring lock
1118- if (m_isCommonBinsFlagValid.load (std::memory_order_acquire))
1119- return m_isCommonBinsFlag.load (std::memory_order_relaxed);
1120- std::lock_guard<std::mutex> lock{m_isCommonBinsMutex};
1121-
1122- // after acquiring lock, check valid flag again
1115+ // check valid flag - other threads may have updated flags
11231116 if (m_isCommonBinsFlagValid.load (std::memory_order_acquire))
11241117 return m_isCommonBinsFlag.load (std::memory_order_relaxed);
1125-
11261118 m_isCommonBinsFlag.store (value, std::memory_order_relaxed);
11271119 m_isCommonBinsFlagValid.store (true , std::memory_order_release);
11281120 return value;
@@ -1133,11 +1125,7 @@ bool MatrixWorkspace::setCommonBinsFlag(const bool value) const {
11331125 * @return whether the workspace contains common X bins
11341126 */
11351127bool MatrixWorkspace::isCommonBins () const {
1136- auto begin = std::chrono::high_resolution_clock::now ();
1137- Instrumentation::AlgoTimeRegister::Instance ();
11381128 if (m_isCommonBinsFlagValid.load (std::memory_order_acquire)) {
1139- auto end = std::chrono::high_resolution_clock::now ();
1140- Instrumentation::AlgoTimeRegister::Instance ().addTime (" isCommonBinsCache" , begin, end);
11411129 return m_isCommonBinsFlag.load (std::memory_order_relaxed);
11421130 }
11431131
@@ -1159,48 +1147,63 @@ bool MatrixWorkspace::isCommonBins() const {
11591147
11601148 // If true, we may return here.
11611149 if (commonPtr) {
1162- auto end = std::chrono::high_resolution_clock::now ();
1163- Instrumentation::AlgoTimeRegister::Instance ().addTime (" isCommonBinsComPtr" , begin, end);
11641150 return setCommonBinsFlag (true );
11651151 }
11661152
11671153 // Check that that size of each histogram is identical.
11681154 const size_t numBins = x (0 ).size ();
11691155 for (size_t i = 1 ; i < numHist; ++i) {
11701156 if (x (i).size () != numBins) {
1171- auto end = std::chrono::high_resolution_clock::now ();
1172- Instrumentation::AlgoTimeRegister::Instance ().addTime (" isCommonBinsSize" , begin, end);
11731157 return setCommonBinsFlag (false );
11741158 }
11751159 }
11761160
1161+ // locb before expensive action
1162+ std::lock_guard<std::mutex> lock{m_isCommonBinsMutex};
1163+ // check valid flag after lock
1164+ if (m_isCommonBinsFlagValid.load (std::memory_order_acquire))
1165+ return m_isCommonBinsFlag.load (std::memory_order_relaxed);
1166+
11771167 const auto &x0 = x (0 );
11781168 // Check that the values of each histogram are identical.
11791169 std::atomic<bool > commonValues{true };
1170+ bool threadSafe = this ->threadSafe ();
11801171 PARALLEL_FOR_IF (this ->threadSafe ())
11811172 for (int i = 1 ; i < static_cast <int >(numHist); ++i) {
1182- if (commonValues) {
1173+ if (commonValues. load (std::memory_order_relaxed) ) {
11831174 const auto specIndex = static_cast <std::size_t >(i);
11841175 const auto &xi = x (specIndex);
1176+ // Early exits same X storage.
1177+ if (&xi == &x0) {
1178+ continue ;
1179+ }
11851180 for (size_t j = 0 ; j < numBins; ++j) {
11861181 const double a = x0[j];
11871182 const double b = xi[j];
1188- // Check for NaN and infinity before comparing for equality
1189- if (std::isfinite (a) && std::isfinite (b)) {
1190- if (std::abs (a - b) > EPSILON) {
1191- commonValues = false ;
1192- break ;
1193- }
1194- // Otherwise we check that both are NaN or both are infinity
1195- } else if ((std::isnan (a) != std::isnan (b)) || (std::isinf (a) != std::isinf (b))) {
1196- commonValues = false ;
1183+ // Early exit for exact equality
1184+ if (a == b) {
1185+ continue ;
1186+ }
1187+ // Early exit for nan/if scenarios
1188+ bool aIsNan = std::isnan (a);
1189+ bool bIsNan = std::isnan (b);
1190+ bool aIsInf = std::isinf (a);
1191+ bool bIsInf = std::isinf (b);
1192+ if ((aIsNan && bIsNan) || (aIsInf && bIsInf)) {
1193+ continue ;
1194+ }
1195+ if ((aIsNan != bIsNan) || (aIsInf != bIsInf)) {
1196+ commonValues.store (false , std::memory_order_relaxed);
1197+ break ;
1198+ }
1199+ // check for equality within tolerance
1200+ if (std::abs (a - b) > EPSILON) {
1201+ commonValues.store (false , std::memory_order_relaxed);
11971202 break ;
11981203 }
11991204 }
12001205 }
12011206 }
1202- auto end = std::chrono::high_resolution_clock::now ();
1203- Instrumentation::AlgoTimeRegister::Instance ().addTime (" isCommonBinsValues" , begin, end);
12041207 return setCommonBinsFlag (commonValues.load (std::memory_order_relaxed));
12051208}
12061209
0 commit comments