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

时间:2015-04-26 07:50:01

标签: c++ gcc sse sse2

我只是在玩gcc(g ++)和compilerflags -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上测试了它。

感谢您的帮助。

亲切的问候

费边

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:4)

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

你需要知道的第二件事是双浮动需要SSE2所以如果你想在你的例子中看到SSE和SSE2之间的差异,你应该将double与float进行比较。

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

//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或使用-m32以32位模式进行编译。