Skip to content

Commit f58abb0

Browse files
committed
remove instrumentation and add early exists to optimise tight loop@
1 parent 44d3de7 commit f58abb0

File tree

1 file changed

+32
-29
lines changed

1 file changed

+32
-29
lines changed

Framework/API/src/MatrixWorkspace.cpp

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
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

11161114
bool 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
*/
11351127
bool 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

Comments
 (0)