为何GCC对std::vector<float>条件乘法的向量化远逊于Clang?
如何让GCC对std::vector的循环进行AVX向量化?
考虑以下float类型的循环,使用-O3 -mavx2 -mfma编译:
for (auto i = 0; i < a.size(); ++i) { a[i] = (b[i] > c[i]) ? (b[i] * c[i]) : 0; }
Clang能完美完成向量化:它使用256位ymm寄存器,通过vblendps/vandps指令组合实现最优性能,对应的核心汇编如下:
.LBB0_7: vcmpltps ymm2, ymm1, ymm0 vmulps ymm0, ymm0, ymm1 vandps ymm0, ymm2, ymm0
但GCC的表现差很多:它始终无法突破SSE 128位向量的限制,即使添加-mprefer-vector-width=256参数也没用,生成的核心汇编是逐标量处理的:
.L6: vcomiss xmm0, xmm1 vmulss xmm0, xmm0, xmm1 vmovss DWORD PTR [rcx+rax*4], xmm0
按照GCC向量化文档说明,若将容器替换为固定大小的普通数组,GCC就能正常生成AVX ymm指令的向量化代码,示例如下:
int a[256], b[256], c[256]; auto foo (int *a, int *b, int *c) { int i; for (i=0; i<256; i++){ a[i] = (b[i] > c[i]) ? (b[i] * c[i]) : 0; } }
目前尚未找到针对变长std::vector实现该效果的方法,需要给GCC添加何种提示,才能让它对std::vector的循环进行AVX向量化?
测试基于GCC 13.1与Clang 14.0.0
内容的提问来源于stack exchange,提问作者Vladislav
相关产品推荐
相关产品推荐

