c++ - AVX 4 位整数

标签 c++ c vectorization intrinsics avx

我需要执行以下操作:

 w[i] = scale * v[i] + point

scale 和 point 是固定的,而 v[] 是一个 4 位整数 vector 。

我需要为任意输入 vector v[] 计算 w[] 并且我想使用 AVX 内在函数来加速这个过程。但是,v[i] 是一个 4 位整数 vector 。

问题是如何使用内在函数对 4 位整数执行运算?我可以使用 8 位整数并以这种方式执行操作,但有没有办法执行以下操作:

[a,b] + [c,d] = [a+b,c+d]

[a,b] * [c,d] = [a * b,c * d]

(忽略溢出)

使用 AVX 内在函数,其中 [...,...] 是 8 位整数,a、b、c、d 是 4 位整数?

如果是,是否可以举一个简短的例子来说明它是如何工作的?

最佳答案

只是部分答案(仅添加)和伪代码(应该很容易扩展到 AVX2 内在函数):

uint8_t a, b;          // input containing two nibbles each

uint8_t c = a + b;     // add with (unwanted) carry between nibbles
uint8_t x = a ^ b ^ c; // bits which are result of a carry
x &= 0x10;             // only bit 4 is of interest
c -= x;                // undo carry of lower to upper nibble

如果已知 ab 的第 4 位未设置(即高半字节的最低位),则可以将其排除在 的计算之外>x.

至于乘法:如果所有产品的 scale 都相同,您可能可以通过一些移位和加/减(在必要时屏蔽溢出位)而逃脱。否则,恐怕你需要屏蔽掉每个 16 位字的 4 位,进行操作,最后将它们拼凑在一起。伪代码(没有AVX 8bit乘法,所以需要用16bit字来运算):

uint16_t m0=0xf, m1=0xf0, m2=0xf00, m3=0xf000; // masks for each nibble

uint16_t a, b; // input containing 4 nibbles each.

uint16_t p0 = (a*b) & m0; // lowest nibble, does not require masking a,b
uint16_t p1 = ((a>>4) * (b&m1)) & m1;
uint16_t p2 = ((a>>8) * (b&m2)) & m2;
uint16_t p3 = ((a>>12)* (b&m3)) & m3;

uint16_t result = p0 | p1 | p2 | p3;  // join results together 

关于c++ - AVX 4 位整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44011366/

相关文章:

c - 如何递归访问结构体的某些元素

matlab - 通过给定的真值行索引生成逻辑矩阵的最快方法?

c++ - 使用 SSE 加速浮点 5x5 矩阵 * vector 乘法

python - 在 numpy 中矢量化后的性能损失

c++ - 如何制作对象的范围迭代器以与 boost KMP 一起使用?

c++ - 使用相同方法但不同成员类型构造类的最佳方法

c++ - gcc 链接器 - .obj 转储具有混合源程序集,但在 .elf 中链接时则不然

c++ - 在 Mac 10.6.3 上使用 gsl

c++ - Qt/C++ 中的反射

c - 在 C 中获得无限输入?