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,并且仍然可以重現故障。
總結
以上是生活随笔為你收集整理的Linux sse 地址对齐指令,SSE指令:哪些CPU可以执行原子16B内存操作?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三星为土耳其抗震救灾捐款 300 万美元
- 下一篇: 2023 第一场任天堂直面会:一些惊喜,