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

如何让MSVC识别结构体内部指针不存在别名

MSVC中__restrict关键字对结构体包裹指针的优化问题

MSVC的__restrict关键字直接作用于裸指针时可以正常触发优化,但当指针被结构体包裹后,该关键字的优化效果就消失了。

我编写了如下测试代码:

#include <memory>
#include <intrin.h>

float dot(__m128 a,__m128 b) {
    __m128 tmp = _mm_mul_ps(a,b);
    tmp = _mm_hadd_ps(tmp,tmp);
    return _mm_cvtss_f32(_mm_hadd_ps(tmp,tmp));
}

template<typename T,int Stride=1> struct v_span {
    T *data;

    operator __m128() const {
        if constexpr(Stride == 1) {
            return _mm_load_ps(data);
        } else {
            return _mm_set_ps(data[0],data[Stride],data[Stride*2],data[Stride*3]);
        }
    }

    T &operator[](int i) const { return data[i*Stride]; }
};

template<typename T> struct m_span {
    T *data;

    auto row(int i) const { return v_span<T>{data + i*4}; }
    auto col(int i) const { return v_span<T,4>{data + i}; }
};

void multiply1(m_span<float> out, m_span<const float> a, m_span<const float> b) {
    for(int c=0; c<4; ++c) {
        for(int r=0; r<4; ++r) {
            out.row(r)[c] = dot(a.row(r),b.col(c));
        }
    }
}

void multiply2(float* __restrict out, m_span<const float> a, m_span<const float> b) {
    for(int c=0; c<4; ++c) {
        for(int r=0; r<4; ++r) {
            out[r*4 + c] = dot(a.row(r),b.col(c));
        }
    }
}

void multiply3(float* __restrict _out, m_span<const float> a, m_span<const float> b) {
    m_span<float> out{_out};
    for(int c=0; c<4; ++c) {
        for(int r=0; r<4; ++r) {
            out.row(r)[c] = dot(a.row(r),b.col(c));
        }
    }
}

用Godbolt以/O2 /std:c++20参数编译后观察汇编结果:

  • multiply2的优化效果良好,b.col(c)在外层循环中仅从内存加载一次;
  • multiply3生成的汇编与multiply1完全一致,每次循环都会重新加载b.col(c);
  • 对比之下,Clang对multiply2和multiply3生成的汇编完全相同。

我尝试过以下方法,但都没有效果:

  • 在v_span和m_span内部的指针成员上添加__restrict关键字;
  • 创建包裹float的结构体并添加转换运算符,让out指向不同类型的指针,但发现MSVC默认允许不同类型间的别名,这与Clang和GCC的行为不同。

我清楚可以通过将b.col(c)存储到变量中来规避这个问题,也知道有更高效的计算方式,但这只是简化后的测试示例。实际项目中的函数是兼容固定大小和可变大小向量、矩阵的模板,存在更复杂的计算需求。虽然MSVC的优化能力不如Clang和GCC,并非我的首选编译器,但我希望项目能让任何人都能轻松下载并编译。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:25:12