我最近偶然发现隐式SSE/AVX加载/存储。我认为这些是GCC的一些特殊扩展,但是后来他们意识到他们也在MSVC上工作。Imprets SSE/AVX加载/存储和堆栈
__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中)可能会提高性能?
我用他们很多在宏在那里我可以在任意的指针类型传递。如果它不对齐,你只会得到一个错位错误。编译器应该已经正确地调整堆栈以适应它正在使用的任何SIMD。 – Mysticial
代码或第二行的注释不正确。 '_mm_store_ps(result,a)'应该等于'__m128 * result =(__m128 *)a'。 '_mm_store_ps'的签名是'void _mm_store_ps(float * mem_addr,__m128 a)',其中'mem_addr'必须与16字节边界对齐。 – plasmacel
@plasmacel,你是对的。虽然。我个人绝不会使用隐含的SSE/AVX加载/存储。 –