Uncontended Mutex Guard: Inside vs. Outside the Loop Body
Question 46 / 51 • Correct so far: 0 (0 answered)
Lock Per Iter
long long sumLocked(const std::vector<int>& data, std::mutex& mtx) {
long long sum = 0;
for (int x : data) {
std::unique_lock<std::mutex> lk(mtx);
sum += x;
}
return sum;
}
std::mutex mtx;
long long result = sumLocked(DATA, mtx); Lock Hoisted
long long sumLocked(const std::vector<int>& data, std::mutex& mtx) {
long long sum = 0;
std::unique_lock<std::mutex> lk(mtx);
for (int x : data)
sum += x;
return sum;
}
std::mutex mtx;
long long result = sumLocked(DATA, mtx); Shared test data (shared-setup)
constexpr int kDataSize = 4096;
static std::vector<int> makeData() {
std::vector<int> v(kDataSize);
for (int i = 0; i < kDataSize; ++i) v[i] = i;
return v;
}
static const std::vector<int> DATA = makeData(); For an uncontended mutex, which snippet is faster?
Snippet B is faster for an uncontended mutex. Declaring a std::unique_lock inside the loop body acquires and releases the mutex on every iteration, paying lock/unlock overhead per element. Hoisting the lock outside the loop acquires it once for the entire batch, reducing that overhead to a single acquire and release.
Benchmark results
| Snippet | CPU time / iteration | Speedup |
|---|---|---|
| Lock Hoisted | 120 ns | 128.2× |
| Lock Per Iter | 15.4 us | 1.0× |
Explore the source
Open in Compiler ExplorerQuiz complete. You can return to the question list to restart and compare.