Linux sse 地址对齐指令,SSE指令:哪些CPU可以执行原子16B内存操作?

在《英特尔®64和IA-32架构开发人员手册》中。3A如今包含您提到的内存订购白皮书的规格,在第8.2.3.1节中说,正如您自己指出的那样,

Intel-64内存排序模型可确保以下各项

内存访问指令,似乎要执行组成内存操作

作为单个内存访问:

•读取或写入单个字节的指令。

•读取或写入地址(2字节)对齐的字(2个字节)的指令

字节边界。

•读取或写入地址对齐的双字(4个字节)的指令

在4个字节的边界上。

•读取或写入地址对齐在其上的四字(8字节)的指令

8字节边界。

任何锁定的指令(XCHG指令或其他读-修改-写

带有LOCK前缀的指令)似乎作为不可分割的和

不间断的装载顺序,然后是存储顺序,与对齐方式无关。

现在,由于上面的列表不包含双四字(16字节)的相同语言,因此该体系结构不保证访问16字节内存的指令是原子的。

话虽如此,最后一段确实暗示了一条出路,即带有LOCK前缀的CMPXCHG16B指令。您可以使用CPUID指令确定处理器是否支持CMPXCHG16B(“ CX16”功能位)。

在相应的AMD文档《AMD64技术AMD64体系结构程序员手册》第2卷:系统编程中,我找不到相似的清晰语言。

编辑:测试程序结果

(修改了测试程序,使#迭代次数增加了10倍)

在Xeon X3450(x86-64)上:

0000 999998139 1572

0001 0 0

0010 0 0

0011 0 0

0100 0 0

0101 0 0

0110 0 0

0111 0 0

1000 0 0

1001 0 0

1010 0 0

1011 0 0

1100 0 0

1101 0 0

1110 0 0

1111 1861 999998428

在Xeon 5150(32位)上:

0000 999243100 283087

0001 0 0

0010 0 0

0011 0 0

0100 0 0

0101 0 0

0110 0 0

0111 0 0

1000 0 0

1001 0 0

1010 0 0

1011 0 0

1100 0 0

1101 0 0

1110 0 0

1111 756900 999716913

在Opteron 2435(x86-64)上:

0000 999995893 1901

0001 0 0

0010 0 0

0011 0 0

0100 0 0

0101 0 0

0110 0 0

0111 0 0

1000 0 0

1001 0 0

1010 0 0

1011 0 0

1100 0 0

1101 0 0

1110 0 0

1111 4107 999998099

这是否意味着Intel和/或AMD保证16字节内存访问在这些计算机上是原子的?恕我直言,事实并非如此。它不在文档中作为保证的体系结构行为,因此无法知道在这些特定处理器上16字节内存访问是否确实是原子的,或者测试程序是否仅由于某种原因未能触发它们。因此依靠它是危险的。

编辑2:如何使测试程序失败

哈!我设法使测试程序失败。在与上述相同的Opteron 2435上,具有相同的二进制文件,但是现在通过“ numactl”工具运行它,指定每个线程在单独的套接字上运行,我得到:

0000 999998634 5990

0001 0 0

0010 0 0

0011 0 0

0100 0 0

0101 0 0

0110 0 0

0111 0 0

1000 0 0

1001 0 0

1010 0 0

1011 0 0

1100 0 1不是单个内存访问!

1101 0 0

1110 0 0

1111 1366 999994009

那么,这意味着什么呢?好吧,Opteron 2435可以保证也可以不保证16字节内存访问对于套接字内访问是原子的,但是至少在两个套接字之间的HyperTransport互连上运行的缓存一致性协议不能提供这种保证。

编辑3:应“ GJ”请求,用于线程功能的ASM。

这是为Opteron 2435系统上使用的GCC 4.4 x86-64版本的线程函数生成的asm:

.globl thread2

.type   thread2, @function

thread2:

.LFB537:

.cfi_startproc

movdqa  .LC3(%rip), %xmm1

xorl    %eax, %eax

.p2align 5,,24

.p2align 3

.L11:

movaps  x(%rip), %xmm0

incl    %eax

movaps  %xmm1, x(%rip)

movmskps        %xmm0, %edx

movslq  %edx, %rdx

incl    n2(,%rdx,4)

cmpl    $1000000000, %eax

jne     .L11

xorl    %eax, %eax

ret

.cfi_endproc

.LFE537:

.size   thread2, .-thread2

.p2align 5,,31

.globl thread1

.type   thread1, @function

thread1:

.LFB536:

.cfi_startproc

pxor    %xmm1, %xmm1

xorl    %eax, %eax

.p2align 5,,24

.p2align 3

.L15:

movaps  x(%rip), %xmm0

incl    %eax

movaps  %xmm1, x(%rip)

movmskps        %xmm0, %edx

movslq  %edx, %rdx

incl    n1(,%rdx,4)

cmpl    $1000000000, %eax

jne     .L15

xorl    %eax, %eax

ret

.cfi_endproc

为了完整起见,.LC3是包含thread2使用的(-1,-1,-1,-1)向量的静态数据:

.LC3:

.long   -1

.long   -1

.long   -1

.long   -1

.ident  "GCC: (GNU) 4.4.4 20100726 (Red Hat 4.4.4-13)"

.section        .note.GNU-stack,"",@progbits

另请注意,这是AT&T ASM语法,而不是Windows程序员可能更熟悉的Intel语法。最后,这是进行曲=本机,这使GCC更喜欢MOVAPS;但这没关系,如果我使用march = core2,它将使用MOVDQA来存储到x,并且仍然可以重现故障。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值