gpt4 book ai didi

sse - 隐式 SSE/AVX 加载/存储和堆栈

转载 作者:行者123 更新时间:2023-12-04 22:45:31 28 4
gpt4 key购买 nike

我最近偶然发现了隐式 SSE/AVX 加载/存储。我认为这些是 GCC 的一些特殊扩展,但后来意识到它们也适用于 MSVC。

__m128 a = *(__m128*)data    // same as __m128 a = _mm_load_ps(data)?
__m128 *b = (__m128*)result; // same as _mm_store_ps(result, a)?

这些隐式加载/存储的正确语法是什么?

据我所读(Addressing a non-integer address, and sse),隐式加载/存储使用对齐的加载/存储,因此内存必须正确对齐。假设它们对大多数支持 SSE/AVX 内在函数的编译器(GCC/ICC/MSVC/Clang/MinGW,...)工作相同是否公平?拥有这些隐式加载/存储的动机是什么?

我的下一组问题是关于将 SSE/AVX 寄存器压入和弹出堆栈的。这是如何实现的?如果堆栈不是 16 字节对齐的怎么办?然后它会使用未对齐的加载/存储吗?据我了解,堆栈现在通常是 16 字节对齐的,但不一定是 32 字节对齐的(至少在 64 位模式下)。如果算法具有高 AVX 占用率并且需要频繁地将 AVX 寄存器压入堆栈,那么将堆栈对齐到 32 字节(例如,在 GCC 中使用 mpreferred-stack-boundary)以提高性能是否有意义?

最佳答案

您在这里所做的是将内存重新解释为由 __m128 变量填充的内存。这是有效的,因为 __m128 基本上是 4 个 float (4 个整数,或 2 个 double ,或...)连续写入内存。所以你可以把它当作一个 float 组。唯一的区别是 __m128 按 16 字节对齐,同时保证 float 组仅按 4 位对齐。

这种重新解释最好使用reinterpret_cast:

  // sqrt calculation : b = sqrt(a)
const int N = 1000; // N%4 has to be equal 0!
float a[N] __attribute__((aligned(16))); // Input. Force 16 bytes alignment.
float b[N] __attribute__((aligned(16))); // Result.

for(int i=0; i<N; i+=4) {
__m128 &aVec = reinterpret_cast<__m128&>(a[i]);
__m128 &bVec = reinterpret_cast<__m128&>(c_simd[i]);
bVec = _mm_sqrt_ps(aVec);
}

关于sse - 隐式 SSE/AVX 加载/存储和堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19730120/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com