【发布时间】:2016-02-29 17:28:59
【问题描述】:
我希望现代 C++ 编译器能够生成最快的机器代码。还是在 2016 年我们仍会坚持使用内联汇编? 我需要搜索与一个特定框相交的浮点 3D 边界框。 我对汇编版本的想法是
1. cmpps => register A
2. cmpss => register B
3. C = A & B
4. convert C into "normal" register
5. compare it with zero
6. conditionally jump
即使在使用第 4 个浮点数填充结构之后,GCC 4.4 和 Visual Studio Comunity 2015 也只能使用 comiss 指令一次生成一个浮点比较。是否需要部分 C++ 表达式顺序或这些编译器无法自行优化?
我的测试用例:
struct Vec
{
float x,y,z,w;
};
struct BBox
{
Vec min,max;
};
bool bbox(BBox& b, Vec& v)
{
return
b.min.x <= v.x && v.x <= b.max.x &&
b.min.y <= v.y && v.y <= b.max.y &&
b.min.z <= v.z && v.z <= b.max.z &&
b.min.w <= v.w && v.w <= b.max.w;
}
int main()
{
BBox b;
Vec v;
return bbox(b, v);
}
【问题讨论】:
-
当前 GCC 为 2 月的 GCC 5.3。 2016. 你如何调用它?你试过
gcc -ffast-math -O3 -mcpu=native吗? -
顺便说一句,你为什么要关心一些特定的机器代码......重要的是性能......只有
gcc -S没有优化。如果您想查看生成的汇编代码,请尝试gcc -S -fverbose-asm -ffast-math -mcpu=native -O3。 -
多年来一直不需要内联汇编。您可以使用intrinsics 编写可移植到所有主要x86 编译器的代码。对于
cmpltps、andps、movmaskps,这看起来是一个很好的案例,然后测试整数结果以确保它已设置所有三个位。 (屏蔽用于比较填充的位,并测试== 0b111)。不幸的是,看起来这个单一功能不会自动矢量化。它可能在一个循环中,但仍然可能不是。 -
@MikeMB:我什至没有看
main()的代码。我查看了bbox()的代码。永远不要使用main来查看 gcc 是如何编译的:它会将其标记为“冷”并且优化较少。只需编写接受输入参数并返回结果的函数。