gpt4 book ai didi

用于灰度到 ARGB 转换的 C++ SSE2 或 AVX2 内在函数

转载 作者:太空狗 更新时间:2023-10-29 20:21:56 25 4
gpt4 key购买 nike

我想知道是否要执行 SSE2/AVX2 整数指令或指令序列(或内在函数)以实现以下结果:

给定一行 8 字节像素的形式:

A = {a, b, c, d, e, f, g, h}

有什么方法可以将这些像素加载到包含 8 个 32 位 ARGB 像素的 YMM 寄存器中,以便将初始灰度值广播到每个相应 32 位像素的其他 2 个字节?结果应该是这样的:(0 是 alpha 值)

B = {0aaa, 0bbb, 0ccc, 0ddd, 0eee, 0fff, 0ggg, 0hhh}

我是 vector 扩展的完全初学者,所以我什至不确定如何处理这个问题,或者是否有可能。

如有任何帮助,我们将不胜感激。谢谢!

更新1

感谢您的回答。我仍然有一个问题:

我把这个小例子放在一起,用 VS2015 在 x64 上编译。

int main()
{
unsigned char* pixels = (unsigned char*)_aligned_malloc(64, 32);
memset(pixels, 0, 64);

for (unsigned char i = 0; i < 8; i++)
pixels[i] = 0xaa + i;

__m128i grayscalePix = _mm_load_si128((const __m128i*)pixels);
__m256i rgba = _mm256_cvtepu8_epi32(grayscalePix);
__m256i mulOperand = _mm256_set1_epi32(0x00010101);

__m256i result = _mm256_mullo_epi32(rgba, mulOperand);

_aligned_free(pixels);
return 0;
}

问题是做了之后

__m256i rgba = mm256_cvtepu8_epi32(grayscalePix)

rgba 只设置了前四个双字。后四位全为0。

英特尔开发人员手册说:

VPMOVZXBD ymm1, xmm2/m64
Zero extend 8 packed 8-bit integers in the low 8 bytes of xmm2/m64 to 8 packed 32-bit integers in ymm1.

我不确定这是有意为之还是我仍然遗漏了什么。

谢谢。

最佳答案

更新:@chtz 的回答是一个更好的主意,使用廉价的 128->256 广播负载而不是 vpmovzx 来提供 vpshufb,从而节省随机端口带宽。


按照 Mark 的建议从 PMOVZX 开始。

但在此之后,PSHUFB (_mm256_shuffle_epi8) 将比 PMULLD 快得多,只是它与 PMOVZX 竞争 shuffle 端口。 (而且它在 channel 内运行,因此您仍然需要 PMOVZX)。

因此,如果您只关心吞吐量,而不关心延迟,那么 _mm256_mullo_epi32 不错。但是,如果延迟很重要,或者如果您的吞吐量瓶颈不是每个 vector 2 个洗牌端口指令,那么 PSHUFB 复制每个像素内的字节应该是最好的。

实际上,即使对于吞吐量,_mm256_mullo_epi32 在 HSW 和 BDW 上也很糟糕:p0 为 2 uops(10c 延迟),因此一个端口为 2 uops。

在 SKL 上,p01 为 2 微指令(10c 延迟),因此它可以维持与 VPMOVZXBD 相同的每个时钟吞吐量。但这是一个额外的 1 uop,使其更容易成为瓶颈。

(VPSHUFB 是 1 uop,1c 延迟,对于端口 5,在所有支持 AVX2 的英特尔 CPU 上。)

关于用于灰度到 ARGB 转换的 C++ SSE2 或 AVX2 内在函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40497227/

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