c++内联程序集优化

c++ inline assembly optimizations

本文关键字:优化 程序集 c++      更新时间:2023-10-16

为什么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,因为完全由于编译器优化,循环被"跳过"。对于_asm块,它需要几秒钟的时间。

是否有任何编译器标志来优化内联程序集,或者由于某些不明确的原因而无法实现?

编译器并不真正理解内联汇编,因此认为它可以做任何事情。

通常,当您特别希望在低级别优化某些代码时,会使用内联程序集。如果你正在这样做,为什么你希望编译器进一步优化它?

向已接受的答案添加更多信息

1) 有一些编译器可以跨内联asm进行优化-Xbox 360编译器可以,但这些可能是例外,而不是规则。

2) 有一些工具可以在编译的二进制文件上运行优化,例如这里-这些工具可能能够优化内联asm。

3) 最后,也许也是最恰当的一点,添加内联asm最流行的原因之一是手动滚动数学量大的矢量化SIMD例程,这些例程对于编译器来说太复杂了,无法单独完成。如果你想要这个,那么一个更好的方法是使用内部函数。本质让你两全其美-你可以手动滚动你棘手的例程,然后让编译器为你处理寄存器分配、展开、交织、死代码修剪等。

关于内部函数的一个好例子,请参阅下面的例子-如果定义了"INLINE_SM",它需要大约300ms,否则它会被优化为零,并且需要0ms,即使它们做了类似的事情。

#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;
}