繁体   English   中英

使用GCC写入Atomic 64位

[英]Atomic 64 bit writes with GCC

关于多线程编程,我陷入了困惑,希望有人可以来帮助我。

在做了相当多的阅读之后,我已经明白我应该能够在64位系统1上原子地设置64位int的值。

我发现很多这种阅读很困难,所以我想我会尝试做一个测试来验证这一点。 所以我用一个线程编写了一个简单的程序,它将一个变量设置为两个值中的一个:

bool switcher = false;

while(true)
{
    if (switcher)
        foo = a;
    else
        foo = b;
    switcher = !switcher;
}

另一个会检查foo值的线程:

while (true)
{
    __uint64_t blah = foo;
    if ((blah != a) && (blah != b))
    {
        cout << "Not atomic! " << blah << endl;
    }
}

我设置a = 1844674407370955161; b = 1144644202170355111; 我运行这个程序并没有得到输出警告我说blah是不是ab

很好,看起来它可能是一个原子写...但是,然后,我改变了第一个线程直接设置ab ,如下所示:

bool switcher = false;

while(true)
{
    if (switcher)
        foo = 1844674407370955161;
    else
        foo = 1144644202170355111;
    switcher = !switcher;
}

我重新跑了,然后突然:

Not atomic! 1144644203261303193
Not atomic! 1844674406280007079
Not atomic! 1144644203261303193
Not atomic! 1844674406280007079

改变了什么? 无论哪种方式,我都要给foo分配一个大数字 - 编译器是否以不同的方式处理一个常数,或者我误解了一切?

谢谢!


1: Intel CPU文档,第8.1节,保证原子操作

2: GCC开发列表讨论GCC不保证它在文档中,但内核和其他程序依赖它

反汇编循环,我用gcc得到以下代码:

.globl _switcher
_switcher:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    movl    $0, -4(%rbp)
L2:
    cmpl    $0, -4(%rbp)
    je  L3
    movq    _foo@GOTPCREL(%rip), %rax
    movl    $-1717986919, (%rax)
    movl    $429496729, 4(%rax)
    jmp L5
L3:
    movq    _foo@GOTPCREL(%rip), %rax
    movl    $1486032295, (%rax)
    movl    $266508246, 4(%rax)
L5:
    cmpl    $0, -4(%rbp)
    sete    %al
    movzbl  %al, %eax
    movl    %eax, -4(%rbp)
    jmp L2
LFE2:

因此看起来gcc确实使用具有32位立即值的32位movl指令。 有一个指令movq可以将64位寄存器移动到存储器(或存储器移动到64位寄存器),但它似乎无法设置将立即值移动到存储器地址,因此编译器被强制要么使用临时寄存器,然后将值移动到内存,要么使用movl 您可以尝试使用临时变量强制它使用寄存器,但这可能不起作用。

参考文献:

http://www.x86-64.org/documentation/assembly.html

内部指令的立即值保持32位。

编译器无法通过原子方式分配64位常数,除非首先填充寄存器然后将该寄存器移动到变量。 这可能比直接分配给变量更昂贵,并且由于语言不需要原子性,因此不选择原子解决方案。

英特尔CPU文档是正确的,对齐8字节读/写在最近的硬件上总是原子的(即使在32位操作系统上)。

你没告诉我们,你在32位系统上使用64位硬件吗? 如果是这样,8字节写入很可能被编译器分成两个4字节写入。

只需查看目标代码中的相关部分即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM