std::atomic<int> 与与本机单词对齐的 int 变量,哪个更好?

问题描述 投票:0回答:1
#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>
变量总是安全吗?

c++ performance c++11 atomic lock-free
1个回答
0
投票

让我们检查一下?

#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
© www.soinside.com 2019 - 2024. All rights reserved.