X86 amd和英特尔程序员';s模型兼容性
我已经通读了《英特尔软件开发指南》(第1-3卷) 没有做类似的阅读AMD的编程指南(第1-5卷),我想知道英特尔和AMD的编程模型在哪些方面是相同的 当然,即使在处理器系列中,也会有特定于型号的寄存器,并支持各种扩展和功能 然而,英特尔确实对一些简单的事情做了一些一般性的陈述,总的来说,我不确定这些事情是否适用于AMD。例如:X86 amd和英特尔程序员';s模型兼容性,x86,intel,cpu-architecture,amd-processor,instruction-set,X86,Intel,Cpu Architecture,Amd Processor,Instruction Set,我已经通读了《英特尔软件开发指南》(第1-3卷) 没有做类似的阅读AMD的编程指南(第1-5卷),我想知道英特尔和AMD的编程模型在哪些方面是相同的 当然,即使在处理器系列中,也会有特定于型号的寄存器,并支持各种扩展和功能 然而,英特尔确实对一些简单的事情做了一些一般性的陈述,总的来说,我不确定这些事情是否适用于AMD。例如: 缓存线大小 每种内存类型的内存顺序保证 每个内存类型的原子r/w保证 ect 请注意,我不是专门询问这些示例。我在问,从程序员的角度来看,在编写功能等同的代码方面,A
- 缓存线大小
- 每种内存类型的内存顺序保证
- 每个内存类型的原子r/w保证
- ect
bsr
/bsf eax,ecx
。所以严格来说,这并不总是像写eax那样。我可以在SKL i7-6700k上确认这一点:mov rax,-1
;bsf eax,ecx
(带归零ecx)保留RAX=-1(64位),不截断为2^32-1。但对于非零ECX,写入EAX具有零扩展到RAX的通常效果。)
这对于内核代码尤其重要,特权指令行为可能有更微妙的差异。我认为TLB失效语义大部分是匹配的,例如,可以保证在将无效条目更改为有效条目后,不需要使TLB失效。因此x86不允许“负缓存”,因此想要这样做的实现必须窥探页表存储以获得一致性 其中一些可能是无意的,比如Intel和AMD都有不同的错误,sysret的x86-64地址不规范,这使得在
ptrace
系统调用可能修改了保存的RIP后使用它不安全。在切换到用户堆栈后,内核模式中可能会发生潜在的GP故障,将内核的控制权从可以修改堆栈内存的同一进程转移到另一个用户空间线程。()这就是为什么Linux总是使用iret
,除了常见情况下的快速路径,其中保存的寄存器是干净的。
AMD对未对齐缓存加载/存储的原子性保证较弱:因为AMD,8字节的边界在x86-64上可能很重要。涵盖了它的公共子集
缓存线大小从未正式标准化。实际上,Intel和AMD CPU使用64字节行,在运行时可以使用CPUID以同样的方式在两者上查询
好吧,至少WB的内存顺序规则是相同的,其他类型的内存顺序规则也可能相同,包括WC和LFENCE/SFENCE/MFENCE的交互与
锁添加
。尽管英特尔没有明确说明lock
和xchg
是否与mfence
不同。但你要问的是编程模型本身,而不仅仅是文档在纸上说了些什么。看到和
IDK关于AMD,但NT WC加载可能会在英特尔上使用
lock add
/xchg
重新排序(但我认为,它们不应该与MFENCE一起重新排序,这就是为什么英特尔ucode更新必须加强Skylake上的MFENCE,以阻止OoO exec像LFENCE一样的其他效果,以防止以后的加载进入管道。)@Bee在第一个链接上的回答提到了这一点,请参见。在测试真正的硬件时,总是很难说什么是未来的保证行为,什么只是实现细节,这就是手册的用武之地。嘿,彼得。谢谢你的详细回答——不仅回答了这个问题,还提供了非常相关的例子。维基百科上有一个。此外,以下指令可能引发的功能、排序规则和/或异常在Intel和AMD处理器上也不同:围栏指令、预取指令、序列化指令和clflush
。自我修改代码和交叉修改代码的规则是不同的。对于WB以外的内存类型,内存排序规则存在差异。某些指令或事件对TLB的影响也存在差异。Intel和AMD上的x86之间可能还有许多其他非常细微的差异。由于缺乏形式主义,因此很难确定所有这些属性。popcnt
false dependency已在Cannon Lake上修复。