小编Mos*_*evy的帖子

为什么跨缓存行边界的变量上的原子存储会编译为普通的 MOV 存储指令?

我们看一下代码

#include <stdint.h>
#pragma pack (push,1)
typedef struct test_s
{
    uint64_t a1;
    uint64_t a2;
    uint64_t a3;
    uint64_t a4;
    uint64_t a5;
    uint64_t a6;
    uint64_t a7;
    uint8_t b1;
    uint64_t a8;
}test;

int main()
{
    test t;
    __atomic_store_n(&(t.a8), 1, __ATOMIC_RELAXED);
}
Run Code Online (Sandbox Code Playgroud)

由于我们有打包结构,a8 不是自然对齐的,也应该在不同的 64 字节缓存边界之间分割,但生成的程序集 GCC 12.2 是

main:
        push    rbp
        mov     rbp, rsp
        mov     eax, 1
        mov     QWORD PTR [rbp-23], rax
        mov     eax, 0
        pop     rbp
        ret
Run Code Online (Sandbox Code Playgroud)

为什么它翻译成简单的MOV?在这种情况下 MOV 不是原子的吗?

添加:clang 16 调用原子函数的相同代码并转换为

main:                                   # @main
        push    rbp
        mov     rbp, rsp
        sub …
Run Code Online (Sandbox Code Playgroud)

c x86 gcc atomic memory-alignment

3
推荐指数
1
解决办法
239
查看次数

访问数组越界时到底什么是未定义的?

假设我有以下数组

unsigned char array[5];
Run Code Online (Sandbox Code Playgroud)

所以我试图了解访问中到底什么是未定义的

array[6]
Run Code Online (Sandbox Code Playgroud)

据我了解,编译器将尝试读取内部的值*(array+6),因此它被定义。所以,如果我理解正确的话,未定义的是当你尝试读取未初始化的内存时会发生什么。

如果是这种情况,那么这里的最佳答案说,除非有陷阱表示,否则定义了读取未初始化的值,但我们知道 unsigned char 没有这种表示。

那么这里定义得好吗?它总是会读到吗*(array+6)

c arrays

0
推荐指数
1
解决办法
431
查看次数

编译器是否允许在条件之前重新排序存储?

假设我们有以下代码

int test(bool* flag, int* y)
{
    if(*y)
    {
        *flag = false;
    else
    {
        *flag = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,编译器可以在这里证明写入标志总是会发生,所以我认为以下一个是允许的(我认为这根本不是优化,但只是为了示例)

int test(bool* flag, int* y)
{
    *flag = true;
    if(*y)
    {
        *flag = false;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以现在,我们也将 true 写入 flag if y!=0,但从 as-if 规则的角度来看,这看起来是有效的。

但我仍然认为,这种优化很奇怪,假设*y = true总是这样,所以标志总是假的,所以如果其他线程读取标志变量,他可能会看到 true,尽管它永远不应该发生,所以它会破坏 as-如果统治?优化是否有效?

另外:非原子的情况很清楚,因为它是 UB,并且所有的赌注都取消了,但是如果标志是具有宽松排序的原子的,那么怎么办?

c c++ x86 memory-model

0
推荐指数
1
解决办法
240
查看次数

标签 统计

c ×3

x86 ×2

arrays ×1

atomic ×1

c++ ×1

gcc ×1

memory-alignment ×1

memory-model ×1