首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >par_unseq和“向量化-不安全”函数

par_unseq和“向量化-不安全”函数
EN

Stack Overflow用户
提问于 2020-01-05 16:27:07
回答 2查看 672关注 0票数 4

我对par_unseq执行策略所施加的限制和“向量化-不安全”函数的想法感到困惑。

我的基本想法是:par_unseq执行策略允许编译器执行矢量化,因此单个线程可以在不同的函数实例之间交织指令。正因为如此,使用类似互斥的东西会因为指令的重新排序而导致死锁。

但是,像compare_exchange循环这样的无锁原子算法呢?或者是没有等待的原子算法,比如原子引用计数机制?

我一开始以为这些会没事的。然而,在cppreference.com的解释说:

取消顺序的执行策略是唯一不对函数调用进行排序的情况,这意味着它们可以相互交织。在C++中的所有其他情况下,它们都是不确定顺序的(不能交织)。因此,用户不允许分配或释放内存、获取互斥、使用非锁定的std::原子专门化,或者通常在使用这些策略时执行任何向量化操作(向量化-不安全函数是将另一个函数(例如,synchronize-with同步)与下一个std::mutex::lock同步的函数)。

这是令人困惑的,因为一方面它说没有锁的std::atomic操作是可以的,另一方面它说向量化不安全的函数是另一个函数同步的任何函数。C++标准中的术语“同步与”不仅仅意味着互斥--它意味着任何与另一个同步的原子操作,例如使用std::memory_order_acquire的原子负载,它与使用std::memory_order_release的原子存储同步。这样的操作可以是无锁的,也可以是没有等待的,但仍然可以彼此同步,以保证线程之间的顺序。

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

EN

回答 2

Stack Overflow用户

发布于 2020-01-05 19:40:17

cppreference.com不是权威的。实际的C++标准是关于在未排序的算法中使用atomics的没什么,并且简单地排除了所有向量化-不安全的操作。目标是消除迭代之间的任何依赖。

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

代码语言:javascript
复制
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;
});

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

票数 2
EN

Stack Overflow用户

发布于 2020-01-05 16:48:28

它说你不能使用无锁的std::atomic操作。它没有说您可以使用无锁的std::atomic操作,也没有说您不能使用无锁的std::atomic操作。

因此,使用无锁std::atomic操作是有可能的,但您仍然需要确保它们满足其他条件(比如不与其他函数同步)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59601859

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档