ARM NEON aarch64:如何以优化的方式比较和更新氖寄存器?

时间:2018-04-17 10:52:58

标签: c++ assembly neon arm64

实际上我正试图找出一种比较来自" unsigned short "加载的霓虹灯寄存器值的好方法。阵列。由于我正在处理大型项目,因此无法解释共享整个代码部分。相反,我将分享一个类似的例子,以便每个人都能理解实际的问题场景。

C ++实施:

unsigned short *values = new unsigned short[8];
for(int i=0; i<8; i++){
    if(values[i] > 255){
            values[i] = 255;
    }
}

装配实施:

MOV W3, #255
UMOV W2, V4.H[0]
CMP W2, #0x00FF
CSEL W2,W3, W2, GT
MOV V4.H[0], W2

UMOV W2, V4.H[1]
CMP W2, #0x00FF
CSEL W2,W3, W2, GT
MOV V4.H[1], W2

UMOV W2, V4.H[2]
CMP W2, #0x00FF
CSEL W2,W3, W2, GT
MOV V4.H[2], W2

UMOV W2, V4.H[3]
CMP W2, #0x00FF
CSEL W2,W3, W2, GT
MOV V4.H[3], W2

UMOV W2, V4.H[4]
CMP W2, #0x00FF
CSEL W2,W3, W2, GT
MOV V4.H[4], W2

UMOV W2, V4.H[5]
CMP W2, #0x00FF
CSEL W2,W3, W2, GT
MOV V4.H[5], W2

UMOV W2, V4.H[6]
CMP W2, #0x00FF
CSEL W2,W3, W2, GT
MOV V4.H[6], W2

UMOV W2, V4.H[7]
CMP W2, #0x00FF
CSEL W2,W3, W2, GT
MOV V4.H[7], W2

我知道这是针对此方案的错误程序集实现。是否可以使用更少的指令执行此任务?关于这个比较和更新说明,我没有找到很多装配文件 任何好主意都将受到高度赞赏。谢谢。

1 个答案:

答案 0 :(得分:2)

正如其他人指出的那样,您可以在32位霓虹灯中使用UMIN或VMIN。适用于32位和64位霓虹灯的Sample implementation using neon内在函数:

#include <stdint.h>
#include <arm_neon.h>

void clamp8(uint16_t values[8])
{
    uint16x8_t v = vld1q_u16(values);
    uint16x8_t x255 = vdupq_n_u16(255);
    uint16x8_t clamped = vminq_u16(v, x255);
    vst1q_u16(values, clamped);
}

这会产生这个arm64霓虹灯代码:

ldr q0, [x0]
movi v1.2d, #0xff00ff00ff00ff
umin v0.8h, v0.8h, v1.8h
str q0, [x0]