【发布时间】:2023-03-11 01:42:01
【问题描述】:
除了SSE-copy, AVX-copy and std::copy performance。假设我们需要以下列方式对某个循环进行矢量化:1)通过 AVX 对第一个循环批次(乘以 8)进行矢量化。 2) 将循环的剩余部分分成两批。通过 SSE 对 4 的倍数的批次进行矢量化。 3) 通过串行程序处理整个循环的剩余批次。让我们考虑复制数组的示例:
#include <immintrin.h>
template<int length,
int unroll_bound_avx = length & (~7),
int unroll_tail_avx = length - unroll_bound_avx,
int unroll_bound_sse = unroll_tail_avx & (~3),
int unroll_tail_last = unroll_tail_avx - unroll_bound_sse>
void simd_copy(float *src, float *dest)
{
auto src_ = src;
auto dest_ = dest;
//Vectorize first part of loop via AVX
for(; src_!=src+unroll_bound_avx; src_+=8, dest_+=8)
{
__m256 buffer = _mm256_load_ps(src_);
_mm256_store_ps(dest_, buffer);
}
//Vectorize remainder part of loop via SSE
for(; src_!=src+unroll_bound_sse+unroll_bound_avx; src_+=4, dest_+=4)
{
__m128 buffer = _mm_load_ps(src_);
_mm_store_ps(dest_, buffer);
}
//Process residual elements
for(; src_!=src+length; ++src_, ++dest_)
*dest_ = *src_;
}
int main()
{
const int sz = 15;
float *src = (float *)_mm_malloc(sz*sizeof(float), 16);
float *dest = (float *)_mm_malloc(sz*sizeof(float), 16);
float a=0;
std::generate(src, src+sz, [&](){return ++a;});
simd_copy<sz>(src, dest);
_mm_free(src);
_mm_free(dest);
}
同时使用 SSE 和 AVX 是否正确?我需要避免 AVX-SSE 转换吗?
【问题讨论】:
-
你可以随意混合。只需确保您启用了正确的编译器标志以强制所有 SIMD 指令为 VEX 编码。
-
@Mystical,编译器 - gcc 4.7.,标志 -O2 -msse -msse2 -msse4.2 -mavx -mfpmath=sse。这是正确的吗?
-
是的,没关系。尽管
-mavx是您所需要的。指定任何 SIMD 选项会自动启用它下面的所有选项。 -
@Mystical,我明白不需要 -msse -msse2 -msse4.2 标志吗?
-
正确。任何带有 AVX 的处理器都保证具有 SSE、SSE2、SSE4.2。
标签: c++ performance sse simd avx