gpt4 book ai didi

c++ - 优化项目冲销

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:09:10 24 4
gpt4 key购买 nike

我有一个循环来反转数组中的元素。我已将问题简化并减少为以下内容:

for (int x=0;x<w/2;++x) {
int il = x;
int ir = w-1-x;
type_copy l = data[il];
type_copy r = data[ir];
data[il] = r;
data[ir] = l;
}

此代码反转元素,但速度相当慢。一方面,它不能自动矢量化,因为数组访问是不连续的。另一方面,右侧的访问与理想的缓存遍历相反。最后,可能存在一些停顿,因为下一个循环周期的加载不会在最后一个循环的数据提交之前发生,因为编译器可能无法判断自别名指针从未命中自身。

在我的例子中,sizeof(type_copy) 要么是 4*sizeof(uint8_t) = 4 要么是 4*sizeof ( float ) = 4*4 = 16。因此,请注意字节级反转是 Not Acceptable 。

我的问题是:如何优化这段代码,如果可以的话?

最佳答案

假设您的数据类型如下:

struct float_data
{
float f1;
float f2;
float f3;
float f4;
};

struct uint8_t_data
{
uint8_t f1;
uint8_t f2;
uint8_t f3;
uint8_t f4;
};

您可以尝试 SSE 内在函数。对于 uint8_t_data 有相当好的速度改进:

typedef uint8_t_data type_copy;

for (int x = 0; x<w / 2; x += 4)
{
int il = x;
int ir = w - 1 - x - 3;

__m128i dl = _mm_loadu_si128((const __m128i*)&data[il]);
__m128i dr = _mm_loadu_si128((const __m128i*)&data[ir]);
_mm_storeu_si128((__m128i*)&data[ir], _mm_shuffle_epi32(dl, _MM_SHUFFLE(0, 1, 2, 3)));
_mm_storeu_si128((__m128i*)&data[il], _mm_shuffle_epi32(dr, _MM_SHUFFLE(0, 1, 2, 3)));
}

输出:

g++ -O3 non vectorized: 16ms
g++ -O3 vectorized: 5ms

但是对于 float_data 并没有太大的速度提升:

typedef float_data type_copy;

for (int x = 0; x<w / 2; x+=2) {
int il = x;
int ir = w - 1 - x - 1;

__m256 dl = _mm256_loadu_ps((const float*)&data[il]);
__m256 dr = _mm256_loadu_ps((const float*)&data[ir]);

_mm256_storeu_ps((float*)&data[ir], _mm256_permute2f128_ps(dl, dl, 1));
_mm256_storeu_ps((float*)&data[il], _mm256_permute2f128_ps(dr, dr, 1));

}

输出:

g++ -O3 -mavx non vectorized: 27ms
g++ -O3 -msse4.2 non vectorized: 25ms
g++ -O3 -mavx vectorized: 24ms

关于c++ - 优化项目冲销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30970212/

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