【发布时间】:2016-02-29 03:50:02
【问题描述】:
我需要将 16 位整数值的大数组从 big-endian 格式转换为 little-endian 格式。
现在我使用以下函数进行转换:
inline void Reorder16bit(const uint8_t * src, uint8_t * dst)
{
uint16_t value = *(uint16_t*)src;
*(uint16_t*)dst = value >> 8 | value << 8;
}
void Reorder16bit(const uint8_t * src, size_t size, uint8_t * dst)
{
assert(size%2 == 0);
for(size_t i = 0; i < size; i += 2)
Reorder16bit(src + i, dst + i);
}
我使用 GCC。目标平台是 ARMv7 (Raspberry Phi 2B)。
有什么办法可以优化吗?
加载音频样本时需要这种转换,这些样本可以是小端格式也可以是大端格式。当然它现在不是瓶颈,但它需要大约 10% 的总处理时间。而且我认为对于这么简单的操作来说太过分了。
【问题讨论】:
-
这真的是瓶颈吗?你量过吗?你有简介吗?
-
如果我没记错的话,有一个专门的组装说明可以做到这一点!但我不记得名字了
-
@hanshenrik: x86-64 上的
bswap。或 GCC 中的__builtin_bswap。 -
你为什么要使用那些愚蠢的演员表?例如,您要丢弃
const限定符,这正是不使用 C 样式强制转换的原因。您已经有一个字节数组,为什么要从某个可能未对齐的地址中提取更大的类型,只是为了移动该更大类型中的字节并再次存储它们?只要想想输入数组中的哪个字节属于输出数组的哪个字节! -
您的
Reorder16bit代码违反了严格的别名规则。您必须使用-fno-strict-aliasing,加上对齐检查,以保证正确操作,这可能会减慢您的其余代码。更好的选择是编写简单、正确的代码并告诉编译器对其进行优化。这就是编译器的用途。