为什么Visual Studio C ++编译器默认情况下不会优化以下代码?
#include "ctime"
#include "iostream"
#define BIG_NUM 10000000000
int main() {
std::clock_t begin = clock();
for (unsigned long long i = 0; i < BIG_NUM; ++i) {
__asm
{
nop
}
}
std::clock_t end = clock();
std::cout << "time: " << double(end - begin) / CLOCKS_PER_SEC;
std::cin.get();
}
没有_asm
块,操作时间始终为0,因为循环是&#34;跳过&#34; 完全由于编译器优化。使用_asm
块只需几秒钟。
是否有任何编译器标志来优化内联汇编或由于某些不明原因而无法实现?
答案 0 :(得分:5)
编译器并不真正理解内联汇编,因此假设它可以做任何事情。
当您特别想要在较低级别优化某些代码时,通常会使用内联汇编。如果您正在这样做,为什么您希望编译器进一步优化它?
答案 1 :(得分:0)
在接受的答案中添加更多信息
1)有一些编译器可以跨内联asm进行优化--Xbox 360编译器可以,但这些可能是例外而不是规则。
2)有些工具可以对已编译的二进制文件e.g. here进行优化 - 这些工具很可能能够优化内联asm。
3)最后,也许是最合适的,添加内联asm的最常见原因之一是手动滚动数学重载矢量化SIMD例程,这些例程对于编译器来说太复杂了。如果你想要这个,那么更好的方法是使用intrinsics。内在函数为您提供了两全其美的优势 - 您可以手动处理棘手的例程,然后让编译器为您处理寄存器分配,展开,交错,死代码修剪等。
有关内在函数的一个很好的例子,请参阅下面的示例 - 如果定义'INLINE_ASM',它需要大约300ms,否则它将被优化为零,即使它们执行类似的操作也需要0 ms。
#include <windows.h>
#include <iostream>
int main()
{
auto tc = ::GetTickCount();
for(int i=0; i<1024 * 1024 * 1024; ++i)
{
#if INLINE_ASM
_asm
{
paddw xmm0, xmm0;
}
#else
_mm_add_epi16(__m128i(), __m128i());
#endif
}
std::cout << "Took " << ::GetTickCount()-tc << " milli-seconds!" << std::endl;
}