首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在英特尔上,来自<stdatomic.h>的atomic_store/load是否适用于未对齐的跨缓存行数据?

在英特尔上,来自<stdatomic.h>的atomic_store/load是否适用于未对齐的跨缓存行数据?
EN

Stack Overflow用户
提问于 2017-08-17 16:09:59
回答 1查看 236关注 0票数 6

使用atomic_store存储的数据和使用atomic_load加载的数据是否始终保持一致?

具体地说:在现代英特尔处理器上,C11程序访问故意放在高速缓存线之间边界上的64位数据。它使用atomic_store & atomic_load (来自<stdatomic.h>)从多个线程(运行在不同的内核上)访问这些数据。

数据是否总是一致的,或者加载数据(atomic_load)有时会有一些字节属于旧值,而另一些字节属于新值?

下面是程序的基本结构和变量定义,以及程序中有趣的部分,它们是在一个循环中从多个线程并行发生的:

代码语言:javascript
复制
struct Data {
    uint8_t bytes[CACHELINE__BYTECOUNT - 4];
    atomic_uint_fast64_t u64;
} __attribute__((packed)) __attribute__((aligned ((CACHELINE__BYTECOUNT))));

#define VAL1 (0x1111111111111111)
#define VAL2 (0xFFFFFFFFFFFFFFFF)

static struct Data data = { .u64 = VAL1 };

...

    for (uint32_t j = 0; j < 1000; j++) {
        atomic_store(&data.u64, VAL1);
        atomic_store(&data.u64, VAL2);
    }
    const uint64_t val = atomic_load(&data.u64);
    /* is 'val' always VAL1 or VAL2? */

(完整的可运行程序:https://gist.github.com/sinelaw/1230d4675d6a4fff394110f17e463954)

用gcc 6.3.0和clang 3.7检查一下,发现它不是原子的:

代码语言:javascript
复制
$ clang -std=c11 -Wall -Wextra /tmp/atomic.c -o /tmp/atomic -lpthread
$ /tmp/atomic
ERROR: oh no, got: 11111111FFFFFFFF

所以要么是程序中有bug,要么是我误解了<stdatomic.h>,要么是编译器中有bug。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-17 16:38:10

正确编写的程序无法获取未正确对齐的对象。正确对齐的int64不能跨越缓存线。

所以你的问题的答案是:你的程序中有一个bug。您通过使用非标准构造(__attribute__)来破坏事物而故意引入的错误。

编译器不遗余力地确保stdatomic对未对齐的值有效,这将是疯狂的,因为这将需要一个全局锁,而这正是stdatomic特别要避免的。

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

https://stackoverflow.com/questions/45729756

复制
相关文章

相似问题

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