gpt4 book ai didi

给定两个 uint8_t 数组,计算 128 个元素的 SAD

转载 作者:太空宇宙 更新时间:2023-11-03 23:26:40 25 4
gpt4 key购买 nike

我有两个 uint8_t 数组,它们都有 64 个元素。我想出的“最佳”方法是加载 4x 16 个元素,将它们放入两个 m128i 寄存器,然后将它们都放入一个 m256 寄存器。这是为两个 uint8_t 数组完成的,如下所示:

__m128i a1, a2, b1, b2, s1, s2;
__m256i u, v, c;

// 128 bit of data x 2
a1 = _mm_set_epi64(*(__m64*)block1, *((__m64*)(block1 + stride)));
block1 += stride + stride;
a2 = _mm_set_epi64(*(__m64*)block1, *((__m64*)(block1 + stride)));

// the upper 128 bits of the result are undefined
u = _mm256_castsi128_si256(a1);
// Copy a to dst, then insert 128 bits from b into dst at the location specified by imm.
u = _mm256_insertf128_si256(u, a2, 0x1);

b1 = _mm_set_epi64(*(__m64*)block2, *((__m64*)(block2 + stride)));
block2 += stride + stride;
b2 = _mm_set_epi64(*(__m64*)block2, *((__m64*)(block2 + stride)));

// the upper 128 bits of the result are undefined
v = _mm256_castsi128_si256(b1);
// Copy a to dst, then insert 128 bits from b into dst at the location specified by imm.
v = _mm256_insertf128_si256(v, b2, 0x1);

我现在有两个m256寄存器,uv,可以计算SAD:

c = _mm256_sad_epu8(u, v);

但是,可能是因为时间太晚,我无法想出更好的方法来获得结果......这是我现在得到的:

s1 = _mm256_extractf128_si256(c, 0x0);
s2 = _mm256_extractf128_si256(c, 0x1);

int p, q;
p = _mm_extract_epi32(s1, 0x0);
q = _mm_extract_epi32(s1, 0x2);
*result += p + q;

p = _mm_extract_epi32(s2, 0x0);
q = _mm_extract_epi32(s2, 0x2);
*result += p + q;

result 是一个 int,如果不清楚的话。

这会生成相当多的指令。在我看来,这是加载我想要的所有单位的唯一方法。但是,这可能不是m256i c 寄存器中获取结果的最佳方式。

你说呢? 你能帮助我以更优化的方式做到这一点吗?

放在一起,函数看起来像这样:

void foobar(uint8_t *block1, uint8_t *block2, int stride, int *result)
{
*result = 0;
int i;
__m128i a1, a2, b1, b2, s1, s2;
__m256i u, v, c;

for (i = 0; i < 2; ++i) {
// loading of uints
// calculating SAD, and getting result

block1 += stride; block2 += stride;
block1 += stride; block2 += stride;
}
}

由于 uint 组织方式的性质,我一次只能加载八个,然后我必须使用 stride 递增地址。一次加载 16 个,会产生不好的结果。

最佳答案

关于从两个字节数组中获取绝对差的总和,这是我使用 SSE 的方式:

__m128i sum1 = _mm_sad_epu8(u,v);
__m128i sum2 = _mm_shuffle_epi32(sum1,2);
__m128i sum3 = _mm_add_epi16(sum1,sum2);
int8_t sum4 = (int8_t)_mm_cvtsi128_si32(sum3);

我现在不能在 AVX2 上测试这个,但这是我会先尝试的未经测试的代码

__m256i sum1 = _mm256_sad_epu8(u,v);
__m256i sum2 = _mm256_shuffle_epi32(sum1,2);
__m256i sum3 = _mm256_add_epi16(sum1,sum2);
__m128i sum4 = _mm_add_epi16(_mm256_castsi256_si128(sum3),
_mm256_extracti128_si256(sum3,1));
int8_t sum5 = (int8_t)_mm_cvtsi128_si32(sum4);

我可以稍后再测试。

关于给定两个 uint8_t 数组,计算 128 个元素的 SAD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25676105/

25 4 0
文章推荐: node.js - Mongoose:按日期运行计划作业查询
文章推荐: javascript - 使用 javascript 删除由 Javascript 创建的
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com