gpt4 book ai didi

c++ - par_unseq 和 "vectorization-unsafe"函数

转载 作者:行者123 更新时间:2023-12-04 13:52:02 24 4
gpt4 key购买 nike

我对 par_unseq 施加的限制感到困惑执行策略和“矢量化不安全”功能的想法。

我明白了:par_unseq执行策略允许编译器执行向量化,因此单个线程可以在不同的函数实例之间交错指令。因此,由于指令重新排序,使用互斥锁之类的东西可能会导致死锁。

但是无锁原子算法呢,比如 compare_exchange 循环呢?或者无需等待的原子算法,例如原子引用计数机制?

我最初认为这些没问题。然而,explanation at cppreference.com说:

Unsequenced execution policies are the only case where function calls are unsequenced with respect to each other, meaning they can be interleaved. In all other situations in C++, they are indeterminately-sequenced (cannot interleave). Because of that, users are not allowed to allocate or deallocate memory, acquire mutexes, use non-lockfree std::atomic specializations, or, in general, perform any vectorization-unsafe operations when using these policies (vectorization-unsafe functions are the ones that synchronize-with another function, e.g. std::mutex::unlock synchronizes-with the next std::mutex::lock)



这令人困惑,因为一方面它说无锁 std::atomic操作没问题,但另一方面它说矢量化不安全函数是任何函数 同步另一个功能。 C++ 标准中的术语“同步于”不仅仅意味着互斥体——它意味着任何与另一个同步的原子操作,例如使用 std::memory_order_acquire 的原子加载使用 std::memory_order_release 与原子存储同步.此类操作可以是无锁或无等待的,但仍会相互同步以保证线程之间的顺序。

那么是否可以使用无锁的获取/释放操作 std::atomic变量(只要所使用的算法实际上是无锁的,即至少有一个线程保证向前进度)?还是 par_unseq禁止任何同步(即只有放松的原子操作才能安全地使用)?

最佳答案

cppreference.com 不是权威。实际的 C++ 标准说 nothing关于在未排序算法中使用原子并简单地排除所有矢量化不安全操作。目标是消除迭代之间的任何依赖性。

无序执行策略允许在同一线程中同时执行多次迭代。这打破了通常的happens-before 语义和前进保证,并可能导致死锁。例如,等待前一次迭代结果的 CAS 循环可能永远不会完成,因为程序被重新排序以执行 8 个这样的循环,然后是 vector 运算。

int a[100]{};
std::atomic<int> busy = 0;
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int& x) {
int expected;
while (!busy.compare_exchange_strong(expected = 0, 1)) {} // might deadlock
x++;
busy = 0;
});

在实践中,您不希望将矢量化代码与原子访问混合使用,因为前者用于性能关键代码,而后者非常慢。向量化编译器也可能无法向量化此类代码。

关于c++ - par_unseq 和 "vectorization-unsafe"函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59601859/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com