1

WinAPI、POSIX 或其他 API-OS 等效扩展中是否存在与 C++11 std::memory_order中所有级别的内存屏障的等效扩展,这些扩展定义了编译器和处理器管道重新排序操作时的优化限制?

enum memory_order {
    memory_order_relaxed,
    memory_order_consume,
    memory_order_acquire,
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst
};

补充: WinAPI 中的一个示例是MemoryBarrier(),但它仅等效于std::atomic_thread_fence( std::memory_order_seq_cst );. 因为 Windows 主要在 x86 系统上工作,普通加载具有获取语义,普通存储具有释放语义:http ://www.stdthread.co.uk/forum/index.php?topic=72.0

但是,即使缓存 L3 (LLC) 和 x86 的管道取消了重新排序优化,load()并且store()根据这些语义 -std::memory_order_acquire/std::memory_order_release也需要禁用编译器优化。

它存在于WinAPI中:

_ReadBarrier 、_WriteBarrier 和 _ReadWriteBarrier编译器内在函数仅防止编译器重新排序。要防止 CPU 重新排序读取和写入操作,请使用 MemoryBarrier 宏。

GCC 中有用于内存模型感知原子操作的内置函数:

__ATOMIC_RELAXED 没有障碍或同步。

__ATOMIC_CONSUME 仅用于屏障和与另一个线程同步的数据依赖性。

__ATOMIC_ACQUIRE 提升代码的障碍并与来自另一个线程的释放(或更强大)语义存储同步。

__ATOMIC_RELEASE 阻止代码下沉并与来自另一个线程的获取(或更强)语义负载同步。

__ATOMIC_ACQ_REL 双向全屏障,并与另一个线程中的获取加载和释放存储同步。

__ATOMIC_SEQ_CST 双向全屏障,并与所有线程中的获取加载和释放存储同步。

我可以使用POSIX禁用此编译器优化吗?

4

2 回答 2

1

通常不是 API 标准的一部分,但在大多数编译器中以一种或另一种形式作为内在函数提供。

例如,Visual Studio 编译器有_ReadBarrier,_ReadWriteBarrier_WriteBarrier. (我只链接了一个,因为从该页面到其余页面都有链接。不,这些不是您列出的所有级别 - 但它们是 x86 具有的所有级别std::memory_order......架构也是。[显然memory_order_relaxed是“无”]。

GCC 具有此处描述的不同类型的内置功能,旨在提供原子更新,而不是专门的障碍。

然而,一般来说,我会把它留给编译器/操作系统来处理原子的事情——使用std::atomic<>和类似的。

于 2013-09-02T11:29:57.230 回答
0

几乎可以肯定不是。该标准的目标是涵盖所有可能发生的情况;您指定所需的最小值,编译器在其环境中提供满足要求的最小值。

至于编译器优化:我想编译器可以评估原子函数的这些参数,并使优化依赖于它,但我怀疑大多数编译器将使用一个更简单的规则:内存访问不重新排序(在编译器级别) 对原子类型的访问。

而且我不确定您要禁用哪些编译器优化。如果编译器与 Posix 兼容,它将禁用跨任何 pthread_...函数的内存访问的所有重新排序;并且可能跨越所有系统功能。(想象一下,如果它在调用 之后重新排序对缓冲区的写入write,或者在调用 之前从缓冲区读取read。)

于 2013-09-02T12:05:51.237 回答