#include <atomic>
#include <thread>
alignas(sizeof(void*)) int n1;
std::atomic<int> n2;
int main() {
std::thread threads[32];
for (auto& thread : threads) {
thread = std::thread([] {
while (true) {
// randomly load and/or store n1, n2
}
});
}
for (auto& thread : threads) {
thread.join();
}
}
考虑上面的代码:
n1
与本机字边界对齐,因此可以在汇编指令级别原子地加载和存储,无需 LOCK 前缀。
n2
是一个std::atomic
,我不确定它是否会在汇编指令级别使用LOCK前缀。
我的问题是:
为了获得最佳性能增益,使用与本机单词对齐
int
变量而不是 std::atomic<int>
变量总是安全吗?
让我们检查一下?
#include <atomic>
#include <thread>
alignas(sizeof(void*)) int n1;
std::atomic<int> n2;
int main()
{
std::thread threads[32];
int individual[32] {0};
int post_sum{0};
constexpr int nr_iterations = 10'000;
int nth_thread = 0;
for (auto& thread : threads) {
thread = std::thread([&individual, nth_thread] {
for (int i = 0; i < nr_iterations; ++i)
{
n2.fetch_add(i);
n1 += i;
individual[nth_thread] += i;
}
});
++nth_thread;
}
nth_thread = 0;
for (auto& thread : threads) {
thread.join();
post_sum += individual[nth_thread];
++nth_thread;
}
std::cout << "Reference: \t" << post_sum << "\n";
std::cout << "n1: \t\t" << n1 << "\n";
std::cout << "n2: \t\t" << n2 << "\n";
return n1 == n2;
}
Reference: 1599840000
n1: 588394298
n2: 1599840000