You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何现代编译器不对简单代码自动生成SSE/AVX向量化指令?

x86-64架构下SSE/AVX向量化的编译器行为疑惑

近期我深入研究x86-64架构,探索SSE(1999年推出)与AVX(2011年推出)指令集的能力。我编写了如下简单向量加法函数:

void compute(const float *a, const float *b, float *c) {
    c[0] = a[0] + b[0];
    c[1] = a[1] + b[1];
    c[2] = a[2] + b[2];
    c[3] = a[3] + b[3];
}

使用gcc与clang,通过以下编译选项构建:

cc -std=c23 -march=native -O3 -ftree-vectorize main.c

但查看反汇编结果后,发现代码并未如预期实现向量化,生成的是逐个处理元素的标量代码:

compute:
  vmovss xmm0, dword ptr [rdi]
  vaddss xmm0, xmm0, dword ptr [rsi]
  vmovss dword ptr [rdx], xmm0
  vmovss xmm0, dword ptr [rdi + 4]
  vaddss xmm0, xmm0, dword ptr [rsi + 4]
  vmovss dword ptr [rdx + 4], xmm0
  vmovss xmm0, dword ptr [rdi + 8]
  vaddss xmm0, xmm0, dword ptr [rsi + 8]
  vmovss dword ptr [rdx + 8], xmm0
  vmovss xmm0, dword ptr [rdi + 12]
  vaddss xmm0, xmm0, dword ptr [rsi + 12]
  vmovss dword ptr [rdx + 12], xmm0
  ret

不过当手动使用intrinsics编写代码时,得到了预期的向量化实现:

#include <xmmintrin.h>

void compute(const float *a, const float *b, float *c) {
    __m128 va = _mm_loadu_ps(a);
    __m128 vb = _mm_loadu_ps(b);
    __m128 vc = _mm_add_ps(va, vb);
    _mm_storeu_ps(c, vc);
}

我知道现代处理器性能强劲,SSE与AVX早已成为主流指令集,但即使显式开启了全优化选项,编译器似乎也不总能充分利用这些指令。为何现代编译器会对如此直白的代码犹豫生成向量化代码?

有人提到4个元素可能不足以体现向量化的性能优势,于是我尝试了处理更大数组的代码,本地编译后仍得到类似的标量结果:

float a[512];
float b[512];
float c[512];

void compute() {  
    for (size_t i = 0; i < 512; i++) 
        c[i] = a[i] + b[i];
}

(注:在本地编译未触发向量化,但在Godbolt上,GCC使用-O3 -march=x86-64-v3选项会自动生成256位AVX指令实现向量化。)

内容的提问来源于stack exchange,提问作者nowox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:18:09