Linux sse 地址对齐指令,SSE指令:哪些CPU可以执行原子16B内存操作?
在《英特爾?64和IA-32架構(gòu)開發(fā)人員手冊(cè)》中。3A如今包含您提到的內(nèi)存訂購白皮書的規(guī)格,在第8.2.3.1節(jié)中說,正如您自己指出的那樣,
Intel-64內(nèi)存排序模型可確保以下各項(xiàng)
內(nèi)存訪問指令,似乎要執(zhí)行組成內(nèi)存操作
作為單個(gè)內(nèi)存訪問:
?讀取或?qū)懭雴蝹€(gè)字節(jié)的指令。
?讀取或?qū)懭氲刂?2字節(jié))對(duì)齊的字(2個(gè)字節(jié))的指令
字節(jié)邊界。
?讀取或?qū)懭氲刂穼?duì)齊的雙字(4個(gè)字節(jié))的指令
在4個(gè)字節(jié)的邊界上。
?讀取或?qū)懭氲刂穼?duì)齊在其上的四字(8字節(jié))的指令
8字節(jié)邊界。
任何鎖定的指令(XCHG指令或其他讀-修改-寫
帶有LOCK前綴的指令)似乎作為不可分割的和
不間斷的裝載順序,然后是存儲(chǔ)順序,與對(duì)齊方式無關(guān)。
現(xiàn)在,由于上面的列表不包含雙四字(16字節(jié))的相同語言,因此該體系結(jié)構(gòu)不保證訪問16字節(jié)內(nèi)存的指令是原子的。
話雖如此,最后一段確實(shí)暗示了一條出路,即帶有LOCK前綴的CMPXCHG16B指令。您可以使用CPUID指令確定處理器是否支持CMPXCHG16B(“ CX16”功能位)。
在相應(yīng)的AMD文檔《AMD64技術(shù)AMD64體系結(jié)構(gòu)程序員手冊(cè)》第2卷:系統(tǒng)編程中,我找不到相似的清晰語言。
編輯:測(cè)試程序結(jié)果
(修改了測(cè)試程序,使#迭代次數(shù)增加了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字節(jié)內(nèi)存訪問在這些計(jì)算機(jī)上是原子的?恕我直言,事實(shí)并非如此。它不在文檔中作為保證的體系結(jié)構(gòu)行為,因此無法知道在這些特定處理器上16字節(jié)內(nèi)存訪問是否確實(shí)是原子的,或者測(cè)試程序是否僅由于某種原因未能觸發(fā)它們。因此依靠它是危險(xiǎn)的。
編輯2:如何使測(cè)試程序失敗
哈!我設(shè)法使測(cè)試程序失敗。在與上述相同的Opteron 2435上,具有相同的二進(jìn)制文件,但是現(xiàn)在通過“ numactl”工具運(yùn)行它,指定每個(gè)線程在單獨(dú)的套接字上運(yùn)行,我得到:
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不是單個(gè)內(nèi)存訪問!
1101 0 0
1110 0 0
1111 1366 999994009
那么,這意味著什么呢?好吧,Opteron 2435可以保證也可以不保證16字節(jié)內(nèi)存訪問對(duì)于套接字內(nèi)訪問是原子的,但是至少在兩個(gè)套接字之間的HyperTransport互連上運(yùn)行的緩存一致性協(xié)議不能提供這種保證。
編輯3:應(yīng)“ GJ”請(qǐng)求,用于線程功能的ASM。
這是為Opteron 2435系統(tǒng)上使用的GCC 4.4 x86-64版本的線程函數(shù)生成的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)向量的靜態(tài)數(shù)據(jù):
.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
另請(qǐng)注意,這是AT&T ASM語法,而不是Windows程序員可能更熟悉的Intel語法。最后,這是進(jìn)行曲=本機(jī),這使GCC更喜歡MOVAPS;但這沒關(guān)系,如果我使用march = core2,它將使用MOVDQA來存儲(chǔ)到x,并且仍然可以重現(xiàn)故障。
總結(jié)
以上是生活随笔為你收集整理的Linux sse 地址对齐指令,SSE指令:哪些CPU可以执行原子16B内存操作?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三星为土耳其抗震救灾捐款 300 万美元
- 下一篇: linux和windows输入法设置,关