假设我有一个执行AES操作的程序。
一些先进的CPU具有AES-NI指令集,而其他CPU则没有。
我必须将我的程序编译为两个可执行文件吗:A_with_aes_ni.exe 和 B_without_aes_ni.exe?
假设我有一个执行AES操作的程序。
一些先进的CPU具有AES-NI指令集,而其他CPU则没有。
我必须将我的程序编译为两个可执行文件吗:A_with_aes_ni.exe 和 B_without_aes_ni.exe?
你所需要的是一个CPU调度器。Agner Fog在他的《优化C++手册》第13章“为不同指令集制作多个版本的关键代码”中有10页的文本可供参考Optimizing C++ manual。他讨论了如何在GCC和ICC中实现这一点。
你只需要一个可执行文件,但需要使用开启和关闭AES功能来编译两个不同的目标文件。然后根据可用的指令集,调度器确定选择哪条代码路径。
我曾尝试在MSVC2010 cpu dispatcher for visual studio for AVX and SSE中实现这一点,但没有成功。不过我觉得现在可能可以实现。
编辑:
在Agner Fog的vectorclass中,他有一个文件dispatch_example.cpp
和instrset_detech.cpp
,其中应该包含大部分你需要制作调度程序所需的内容。你仍然需要找出如何检测CPU是否支持AES。你需要增强intrset_detect.cpp文件。根据wikipedia,当你读取寄存器ECX中的CPUID位23时,如果CPU支持AES,则会被置位。维基百科还有代码示例来读取CPUID(除了instrset_detech.cpp
之外,另一个很好的示例可以在https://github.com/Mysticial/Flops的cpuid.c文件中找到)
elfdump -H
来查看差异。s11u1:jmcp $ elfdump -H /usr/lib/libc/libc_hwcap1.so.1
Capabilities Section: .SUNW_cap
Object Capabilities:
index tag value
[0] CA_SUNW_HW_1 0x86d [ SSE MMX CMOV SEP CX8 FPU ]
Symbol Capabilities:
index tag value
[2] CA_SUNW_ID hrt
[3] CA_SUNW_HW_1 0x40002 [ TSCP TSC ]
Symbols:
index value size type bind oth ver shndx name
[1] 0x000f306c 0x00000225 FUNC LOCL D 0 .text gettimeofday%hrt
[2] 0x000f2efc 0x00000165 FUNC LOCL D 0 .text gethrtime%hrt
Capabilities Chain Section: .SUNW_capchain
Capabilities family: gettimeofday
chainndx symndx name
1 [702] gettimeofday
2 [1] gettimeofday%hrt
Capabilities family: gethrtime
chainndx symndx name
4 [1939] gethrtime
5 [2] gethrtime%hrt
s11u1:jmcp $ elfdump -H /usr/lib/libc/libc_hwcap2.so.1
Capabilities Section: .SUNW_cap
Object Capabilities:
index tag value
[0] CA_SUNW_HW_1 0x1875 [ SSE2 SSE MMX CMOV AMD_SYSC CX8 FPU ]
Symbol Capabilities:
index tag value
[2] CA_SUNW_ID hrt
[3] CA_SUNW_HW_1 0x40002 [ TSCP TSC ]
Symbols:
index value size type bind oth ver shndx name
[1] 0x000f253c 0x00000225 FUNC LOCL D 0 .text gettimeofday%hrt
[2] 0x000f23cc 0x00000165 FUNC LOCL D 0 .text gethrtime%hrt
Capabilities Chain Section: .SUNW_capchain
Capabilities family: gettimeofday
chainndx symndx name
1 [702] gettimeofday
2 [1] gettimeofday%hrt
Capabilities family: gethrtime
chainndx symndx name
4 [1939] gethrtime
5 [2] gethrtime%hrt
猜一下上面的哪个是针对AMD系统的,哪个是针对Intel系统的?
Solaris链接器具有智能功能,在调用进程的_init()之前运行正确的hwcap库。