gpt4 book ai didi

c++ - 在 arm neon 中有效地计算两个不同的数字

转载 作者:太空宇宙 更新时间:2023-11-04 12:46:51 28 4
gpt4 key购买 nike

我有一个包含 16 个整数的数组,我想从这个数组中找到一对整数,它们之间的差异最大。可以使用此(伪)代码计算相异性:

int diss(uint32_t x, uint32_t y)
{ // it could do square for each byte of the number instead.
return
abs(((x >> 24) & 0xFF) - ((y >> 24) & 0xFF)) +
abs(((x >> 16) & 0xFF) - ((y >> 16) & 0xFF)) +
abs(((x >> 8) & 0xFF) - ((y >> 8) & 0xFF)) +
abs(((x >> 0) & 0xFF) - ((y >> 0) & 0xFF));
}

void findDissimilar(uint32_t buf[16], uint32_t& x, uint32_t& y)
{
int maxDiss = 0;
for (int i=0; i<16; ++i)
{
for (int j=0; j<16; ++j)
{
int d = diss(buf[i], bud[j]);
if (d > maxDiss)
{
maxDiss = d;
x = buf[i];
y = buf[j];
}
}
}
}

在输入时 buf 已经在 NEON 寄存器中(如果重要的话)。在输出时我应该得到两个整数(在 neon reg 中可能更好)。我怎样才能在 arm neon 中有效地做到这一点,我应该尝试什么方法?澄清一下,问题的重点是优化 findDissimilar

最佳答案

diss 在 neon 中计算起来很简单,它可能以这种方式实现(未经测试的代码):

uint32x4_t diss_x4(uint32x4_t x4, uint32x4_t y4)
{
uint8x16_t diff = vabdq_u8(vreinterpretq_u8_u32(x4), vreinterpretq_u8_u32(x4));
uint16x8_t m0 = vmull_u8(vget_low_u8(diff), vget_low_u8(diff));
uint16x8_t m1 = vmull_u8(vget_high_u8(diff), vget_high_u8(diff));
uint16x4_t s0 = vpadd_u16(vget_low_u8(m0), vget_high_u8(m0));
uint16x4_t s1 = vpadd_u16(vget_low_u8(m1), vget_high_u8(m1));
uint16x4_t sx = vpadd_u16(s0, s1);
return vmovl_u16(sx);
}

但对于 findDissimilar 来说并不是那么微不足道。我认为最好的方法是执行以下操作: - 加载 4 个 q 寄存器 {q0, q1, q2, q3} 中的所有 16 个整数。 - 第一个 q0 reg 包含 { buf[0], buf[1], buf[2], buf[3] } - 然后我可以循环 15 次并从 4 个输入 q regs 提取到 qext 值,例如第一次迭代的 vextq_u32(q0, q1, 1) 等等。 - 计算 q0 和 qext 之间的最小值。

然后应该对 q1、q2、q3 执行相同的过程。

也许如果我按字节去交错​​ {q0, q1, q2, q3},它可能会得到更好的优化。

关于c++ - 在 arm neon 中有效地计算两个不同的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51145084/

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