我很困惑,微软表示InterlockedExchange需要内存对齐,但是,英特尔文档说LOCK不需要内存对齐。 我错过了什么,或者其他什么? 感谢
来自Microsoft MSDN LibraryPlatform SDK:DLL,进程和线程 InterlockedExchange
Target参数指向的变量必须<32>在32位边界上对齐;否则,此函数将在多处理器x86系统和任何非x86系统上无法预测。
<英特尔软件开发人员手册LOCK指令 在执行伴随指令期间使处理器的LOCK#信号有效(将指令转换为原子指令)。在多处理器环境中,LOCK#信号确保处理器在声明信号时独占使用任何共享内存。
LOCK前缀的完整性不受内存字段对齐的影响。 对于任意错位的字段,会发现内存锁定。
P6和更近期处理器系列中的内存排序
已锁定的说明包含总订单。
软件控制总线锁定
总线锁的完整性不受存储器字段对齐的影响。对于更新整个操作数所需的总线周期,遵循LOCK语义。但是,建议锁定访问在其自然边界上对齐,以获得更好的系统性能: •8位访问的任何边界(锁定或其他)。 •锁定字访问的16位边界。 •锁定双字访问的32位边界。 •锁定四字访问的64位边界。
答案 0 :(得分:6)
曾几何时,Microsoft在x86以外的处理器上支持WindowsNT,例如MIPS,PowerPC和Alpha。这些处理器都需要对齐其互锁指令,因此Microsoft在其规范中提出了要求,以确保这些原语可以移植到不同的架构中。
答案 1 :(得分:1)
即使锁定前缀不需要对齐内存,并且可能用于实现InterlockedExchange()的cmpxchg操作不需要对齐,如果操作系统已启用对齐检查,则cmpxchg将引发对齐检查使用未对齐的操作数执行时的异常(AC)。查看cmpxchg及其类似文档,查看受保护模式异常列表。我不确定Windows是否支持对齐检查,但这并不会让我感到惊讶。
答案 2 :(得分:1)
嘿,I回答了一些与此相关的问题,同时请记住;
我差点忘了,从英特尔TBB开始,他们使用隐式或显式锁定(在某些情况下)加载/存储8位定义;
.code
ALIGN 4
PUBLIC c __TBB_machine_load8
__TBB_machine_Load8:
; If location is on stack, compiler may have failed to align it correctly, so we do dynamic check.
mov ecx,4[esp]
test ecx,7
jne load_slow
; Load within a cache line
sub esp,12
fild qword ptr [ecx]
fistp qword ptr [esp]
mov eax,[esp]
mov edx,4[esp]
add esp,12
ret
EXTRN __TBB_machine_store8_slow:PROC
.code
ALIGN 4
PUBLIC c __TBB_machine_store8
__TBB_machine_Store8:
; If location is on stack, compiler may have failed to align it correctly, so we do dynamic check.
mov ecx,4[esp]
test ecx,7
jne __TBB_machine_store8_slow ;; tail call to tbb_misc.cpp
fild qword ptr 8[esp]
fistp qword ptr [ecx]
ret
end
无论如何,希望能为你解决一些问题。
答案 3 :(得分:-1)