C/C++:-msse 和 -msse2 标志对二进制文件没有任何影响

C/C++: -msse and -msse2 Flags do not have any effect on the binaries?

本文关键字:二进制文件 影响 任何 标志 -msse2 C++ -msse      更新时间:2023-10-16

我只是在玩gcc(g ++)和编译器标志-msse和-msse2。我有一个看起来像这样的小测试程序:

#include <iostream>
int main(int argc, char **argv) {
    float a = 12558.5688;
    float b = 6.5585;
    float result = 0.0;
    result = a * b;
    std::cout << "Result: " << result << std::endl;
    return 0;
}

当我使用以下语句编译它时:

/usr/local/bin/g++-4.9 -W -msse main.cpp -o testsse

/usr/local/bin/g++-4.9 -W -msse2 main.cpp -o testsse2

输出文件二进制相等。但是由于SMID标志的原因,我预计它们并不相同。

所以我的问题是,这些编译器标志对二进制文件没有任何影响吗?我已经在OS X 10.10.3和Fedora 21上测试过它。

感谢您的帮助。

亲切问候

法比安

在你的代码中,涉及非常基本的浮点数学。我敢打赌,如果你打开优化(即使是-O1),它也会被优化出来,因为这些值是常量表达式,因此可以在编译时计算。

使用SSE(movssmulss),因为它是浮点演算的阈值,如果我们愿意的话。SSE2 在这里没有范围。
为了为 SSE2 找到空间,您需要包含更复杂的微积分,这些微积分可能会也可能不会利用 SSE2 中可用的一些指令;你可以查找一些做了什么,做他们的等效工作,看看编译器是否可以利用它们。

您需要知道的第一件事是 SSE2 和 SSE 默认启用并用于 64 位代码。对于 32 位代码,默认值为 x87 指令。

您需要知道的第二件事是双浮点数需要 SSE2,因此如果您想在示例中查看 SSE 和 SSE2 之间的区别,您应该将双精度与浮点数进行比较。

你需要知道的第三件事是如何说服你的编译器不要优化你的计算。一种方法是将代码包装在如下函数中:

//foo.cpp
float foof(float x, float y) {
    return x*y;
}
double food(double x, double y) {
    return x*y;
}

然后g++ -O3 -S foo.cpp显示foof使用mulssfood使用mulsd。如果你想确保它得到正确的结果,你可以像这样链接它

//main.cpp
#include <iostream>   
extern float  foof(float, float);
extern double food(double, double);
int main(void) {
    float af = 12558.5688;
    float bf = 6.5585;
    float resultf = 0.0;
    double ad = af;
    double bd = bf;
    double resultd = 0.0;
    resultf = foof(af, bf);
    resultd = food(ad, bd);
    std::cout << "Resultf: " << resultf << " Resultd: " << resultd << std::endl;
}

然后做g++ -O3 -c foo.cpp然后g++ -O3 main.cpp foo.o.

如果要禁用 SSE 指令,请使用 -mfpmath=387 或以 32 位模式编译 -m32 .