Android 如何将uint8x8\u t加载到ARM中的float32x4中?

Android 如何将uint8x8\u t加载到ARM中的float32x4中?,android,c,optimization,arm,neon,Android,C,Optimization,Arm,Neon,我正在研究一种图像处理算法,我正在研究如何使用霓虹灯对其进行优化。 该算法包括将每个(RGBA,8位)像素乘以某个权重,进行加法,最后转换回uint8_t值。 我遇到的第一个问题是如何有效地加载单个uint8_t像素并将其转换为NEON的float32x4_t。我在参考中搜索了一个合适的转换,但找不到一个合适的转换,所以我求助于这个丑陋的代码: const uint8_t* psrc = ...; // pointer to image data float rgba[4]; for (int

我正在研究一种图像处理算法,我正在研究如何使用霓虹灯对其进行优化。 该算法包括将每个(RGBA,8位)像素乘以某个权重,进行加法,最后转换回uint8_t值。 我遇到的第一个问题是如何有效地加载单个uint8_t像素并将其转换为NEON的float32x4_t。我在参考中搜索了一个合适的转换,但找不到一个合适的转换,所以我求助于这个丑陋的代码:

const uint8_t* psrc = ...; // pointer to image data
float rgba[4];
for (int c = 0; c < 4; ++c) {
  rgba[c] = *psrc++;
}
float32x4_t srcpix = vld1q_f32(rgba);

据我所知,
NEON
仅支持32位转换(使用
vcvt…()
您可以在
float32x4\u t
int32x4\u t
之间进行转换(例如)。因此,您需要将
uint8x8\u t
转换为
uint32x4x2\u t
,然后对
uint32x4x2\u t
的两部分使用
vcvt

编辑:
不幸的是,我无法为您提供代码,因为我没有花很多时间使用它,也记不住命令。

所以您想将它们转换为浮点值进行一些算术运算,并将结果转换回int?这与人们所说的优化恰恰相反

在霓虹灯真正发光的地方,坚持使用定点算法

我很难想象在任何情况下,转换为float处理ARGB格式都是有意义的,因为每个通道的大小(和精度)只有8位

很明显,你试图让NEON在ARM完成浮点运算的同时进行来回转换,但这恰恰是利用NEON的错误方法

适当的NEON优化功能应能让NEON自行处理数据加载、算法和数据存储。如果操作得当,我相信NEON版本的运行速度将比当前版本快20倍以上,接近memcpy速度。-霓虹灯的定点运算功能非常强大


请透露更多信息,你正在尝试做什么。也许我能帮上忙。

VTBX查表指令可以在一次操作中进行无符号8bit-32位扩展,但不幸的是,输出是一个neon寄存器(将是
uint32x2\u t
),所以要“填充”一个
uint32x4\u t
,您需要调用它两次。对于
uint8x8\t
源的所有八个字节,您必须执行以下操作:

uint8x8_t bvec = vld1_u8(psrc);

uint8x8x4_t tbl = {
    { 0, -1, -1, -1, 1, -1, -1, -1 },
    { 2, -1, -1, -1, 3, -1, -1, -1 }
    { 4, -1, -1, -1, 5, -1, -1, -1 }
    { 6, -1, -1, -1, 7, -1, -1, -1 }
};

uint32x4_t ivec[2] = {
    {
    vreinterpret_u32_u8(vtbx1_u8(tbl[0], bvec, 0)),
    vreinterpret_u32_u8(vtbx1_u8(tbl[1], bvec, 0))
    },
    {
    vreinterpret_u32_u8(vtbx1_u8(tbl[2], bvec, 0)),
    vreinterpret_u32_u8(vtbx1_u8(tbl[3], bvec, 0))
    }
};

float32x4_t vec[2] = { vcvtq_f32_u32(ivec[0]), vcvtq_f32_u32(ivec[1]) };

我不认为这比你找到的方法更简单。查找表也来自内存,因此速度可能较慢。然后还需要
vreinterpress…
。。。这是一个免费的操作,但看起来很粗糙。

感谢您的快速回复,我想出了一个与您的方法类似的不同版本。对我来说,它看起来仍然有很多拓宽和转换。@avish这与我所说的完全一样。谢谢你的评论——我正在尝试霓虹灯优化,我确实感觉自己在黑暗中刺痛。在我的C参考impl中,我将RGBA像素的每个通道乘以相同的浮动权重。我认为使用霓虹灯指令(vmlaq_n_f32)可能会有所帮助。你是说浮点运算是在ARM上运行的?这里我透露了更多信息:):
uint8x8_t bvec = vld1_u8(psrc);

uint8x8x4_t tbl = {
    { 0, -1, -1, -1, 1, -1, -1, -1 },
    { 2, -1, -1, -1, 3, -1, -1, -1 }
    { 4, -1, -1, -1, 5, -1, -1, -1 }
    { 6, -1, -1, -1, 7, -1, -1, -1 }
};

uint32x4_t ivec[2] = {
    {
    vreinterpret_u32_u8(vtbx1_u8(tbl[0], bvec, 0)),
    vreinterpret_u32_u8(vtbx1_u8(tbl[1], bvec, 0))
    },
    {
    vreinterpret_u32_u8(vtbx1_u8(tbl[2], bvec, 0)),
    vreinterpret_u32_u8(vtbx1_u8(tbl[3], bvec, 0))
    }
};

float32x4_t vec[2] = { vcvtq_f32_u32(ivec[0]), vcvtq_f32_u32(ivec[1]) };