gpt4 book ai didi

x86 获取语义获取和增量?

转载 作者:行者123 更新时间:2023-12-04 20:45:38 25 4
gpt4 key购买 nike

假设我有一个时间戳计数器。

 static uint32_t _Atomic timestamp = 0U;

static inline uint32_t get_ts(void) {
return atomic_fetch_add_explicit(&timestamp, 1, memory_order_acquire);
}

假设我有一些并发代码,并且我想通过实验测试并记录内存重新排序。

 for (;;) {
uint32_t ts1 = get_ts();
struct result result_a = do_a();

uint32_t ts2 = get_ts();
struct result result_b = do_b();

log(ts1, &result_a);
log(ts2, &result_b);
}

在 c11 内存模型下,do_a 可能会通过 do_b() 重新排序到 get_ts 之前。

 for (;;) {
uint32_t ts1 = get_ts();
uint32_t ts2 = get_ts();
struct result result_b = do_b();
struct result result_a = do_a();

log(ts1, &result_a);
log(ts2, &result_b);
}

但是,假设编译器不会对 x86 上的内容进行重新排序,lock xadd 会成为所有加载和存储的障碍。因此,x86(但不是编译器)实际上不可能执行此重新排序,因为 get_ts 调用充当获取释放栅栏。

x86 上有没有办法实现真正​​的获取语义获取和增量?

最佳答案

是否允许编译器对 do_ado_b 重新排序取决于这些函数的作用。原子优化是可能的[ 1 ],但须遵守 C11 标准第 5.1.2.4 节[ draft ]。 (我相信这是相关的。)

网站cppreference.com提供了有关该主题的重新措辞的 View ,包括 memory_order_acquirememory_order_release 语义的定义。
具有获取语义的加载和具有释放语义的存储可以实现为:

Acquire load                       Release store
Load #StoreStore
#LoadLoad #LoadStore
#LoadStore Store

其中 # 表示栅栏(内存屏障)。
然而,在 Intel memory ordering white paper ,明确指出 LoadLoad、StoreStore 和 LoadStore 重新排序永远不会在临时加载/存储上执行。
因此,释放获取语义在 x86 上是免费的。

这不是使用像lock xadd这样的锁定(从而序列化)指令的问题;即使使用简单的 mov 指令,释放获取语义也始终受到尊重。
请注意,获取语义与获取加载之前执行的存储无关;它对存储进行排序并在其之后加载。

关于你最后一个问题,有点不清楚。

Is there a way on x86 to have a true acquire semantics fetch and increment?

序列化所有指令的实现具有获取语义。在这方面,x86 不做任何重新排序。

如果您的意思是,有没有一种方法可以实现顺序不一致的原子操作(C11 含义),那么答案是否定的。
您可以在英特尔手册中找到相关部分,也可以在上面链接的白皮书中找到它。它说:

  1. In a multiprocessor system, locked instructions have a total order.
  2. Loads and stores are not reordered with locked instructions.

通过要求原子 RMW(读取-修改-写入)操作,您还可以对原子变量强制执行顺序一致的顺序。

关于x86 获取语义获取和增量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44617003/

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