如何使用neon intrinsics准确地将uchar转换为float32,反之亦然

时间:2016-02-02 00:56:04

标签: intrinsics

我正在努力优化一些用于视频过滤的c ++代码,并使用内在函数来实现。但是,在加载和存储到不同类型的矢量时,我仍然无法确定如何键入我的值,同时仍然保持准确性。

我需要将我的uchar vector img的4个值存储到float32x4_t向量中。

我使用的第一种方法是:

  float32x4_t first_val = {(float32_t)img.data[STEP0*i + STEP1*j],
                                (float32_t)img.data[STEP0*i + STEP1*(j + 1)],
                                (float32_t)img.data[STEP0*i + STEP1*(j + 2)],
                                (float32_t)img.data[STEP0*i + STEP1*(j + 3)]
                                }; 

虽然有效,但现在正在阻碍我的速度。所以我试过了:

float32x4_t first_val = vld1q_f32((float32_t*)&img.data[STEP0*i + STEP1*j]);

哪个不起作用。我怀疑它是因为它将我的8位像素中的4个转换为一个浮点数并基本上将其解释为垃圾。

我考虑使用vreinterpret {q} _dsttype_srctype来避免这个问题,但示例代码似乎只能将x大小的var类型重新解释为相同大小的另一个vartype。我在存储和加载时遇到了同样的问题。

如果有人知道从uchar准确传出的正确方法 - > float32和float32-> uchar请帮忙。

1 个答案:

答案 0 :(得分:0)

对图像数据的索引计算相当昂贵,而且您正在进行4次。我假设数据[]按顺序传输,但由于缺少代码,我无法判断。这个假设基于你试图在第二个例子中使用vld1q_f32()的事实,并且这要求数据按顺序排列。

无论如何,试试这个:

uchar* p = &img.data[STEP0*i + STEP1*j];

float32x4_t first_val = {(float32_t)*p++,
                            (float32_t)*p++,
                            (float32_t)*p++,
                            (float32_t)*p++
                            }; 

如果你可以在循环之外初始化第一行,那么你会看到一个显着的增长。

如果你想要它更快,那么请考虑一下UNION关键字,这可能比它的价值更麻烦。就我个人而言,我不推荐它。

vld1q_f32()似乎是相同的格式,而不是混合2数据类型。你为什么不工作的原因是我怀疑发生了什么。