【问题标题】:gcc options to use i87, AVX simultaneously but nor SSEgcc 选项同时使用 i87、AVX 但也不使用 SSE
【发布时间】:2012-11-23 06:43:03
【问题描述】:
当为支持AVX 扩展的处理器编译时(比如-m64 -march=corei7-avx -mtune=corei7-avx 适用),同时使用-mfpmath=both -mavx 键是否有意义?这不是导致编译器同时使用三组指令(i87、SSE、AVX)吗?或者只是 i87 用于标量(在某种意义上),AVX 仅用于向量?
【问题讨论】:
标签:
gcc
sse
instruction-set
avx
fpu
【解决方案1】:
AVX 寄存器只是 SSE 寄存器的扩展。您不能混合使用 SSE 和 AVX 指令来增加可用寄存器的数量(您仍然可以混合使用 x87 和 AVX 指令,我认为这就是 -mfpmath=both 在这种情况下所做的)。
例如,请参阅this 页面上的“混合 AVX 和 SSE”讨论。
【解决方案2】:
你通常不想要这个;我不认为 gcc 在决定使用 x87 时不够聪明,因为注册压力很大,因此值得。
x87 和 SSE/AVX 指令在普通 x86 CPU(Intel 和 AMD)上竞争相同的 FP 执行单元,因此您不会通过交错获得更多吞吐量。
通常你应该只使用-mfpmath=sse(这意味着与-mavx一起使用时的AVX,或者更好的-mfpmath=sse -march=native。x86-64的默认值是sse,所以-mfpmath=sse只会改变-m32的任何内容, 爱不释手。
-mfpmath=both 的主要好处是更多的总寄存器,但管理 x87 寄存器堆栈通常需要额外的指令。在 x87 和 AVX 之间移动数据还需要存储/重新加载(存储转发往返,Haswell 上约 6 个周期延迟,http://agner.org/optimize/),因此只有当您有两组独立的计算供编译器交错时,它才真正有用。否则它并不比正常的溢出/重新加载更好。
Last time I looked at gcc -O3 -mfpmath=both,结果并不令人印象深刻:https://godbolt.org/g/p2KLEC 显示 gcc5.4 使用一些存储/重新加载在 x87 和 xmm (AVX) 寄存器之间反弹数据。最好只在内存中保留一些常量。