【发布时间】:2017-01-16 11:31:53
【问题描述】:
我需要在使用 ARM Cortex M4 处理器的嵌入式系统中尽快交换缓冲区中的备用字节。我使用 gcc。数据量是可变的,但最大值略高于 2K。是否转换了一些额外的字节并不重要,因为我可以使用一个过大的缓冲区。
我知道 ARM 有 REV16 指令,我可以用它来交换 32 位字中的备用字节。我不知道的是:
有没有办法在 gcc 中得到这条指令而不求助于汇编程序?
__builtin_bswap16内在函数似乎只对 16 位字进行操作。一次转换 4 个字节肯定比转换 2 个字节要快。Cortex M4 是否具有重新排序缓冲区和/或进行寄存器重命名?如果没有,当我在部分展开的循环中转换缓冲区的双字时,我需要做些什么来最大限度地减少管道停顿?
例如,这段代码是否有效,其中REV16 被适当地定义为解析 (1):
uint32_t *buf = ... ;
size_t n = ... ; // (number of bytes to convert + 15)/16
for (size_t i = 0; i < n; ++i)
{
uint32_t a = buf[0];
uint32_t b = buf[1];
uint32_t c = buf[2];
uint32_t d = buf[3];
REV16(a, a);
REV16(b, b);
REV16(c, c);
REV16(d, d);
buf[0] = a;
buf[1] = b;
buf[2] = c;
buf[3] = d;
buf += 4;
}
【问题讨论】:
-
inline assembler 有什么问题。它不可移植,但
__builtin_bswap16也不是。__builtin_bswap16仅适用于具有多种 CPU 类型的 GCC。主要针对针对 GCC 的 libc 编写者。大多数人可能会接受在移植时抛出错误的高度针对性的条件代码。放一些好的cmets。请参阅:Linux 内核中的bswapdi2.S。您的系统可能会受到内存限制而不是 CPU 限制。 -
请参阅:godbolt,使用 'bswapdi2.s' 的掩码方法用于 arch
-
谢谢,如果没有其他方法同样快,我可以使用内联汇编程序。我可以只使用:
asm("rev16 a,a");将 rev16 操作应用于上面示例中的变量a吗? -
@dc42 以godbolt.org/g/JyZBZp 为例,您可以看到编译器内联了对
Rev16的函数调用是内联的,因此您最终得到了一条指令。
标签: gcc arm endianness