拷贝期间的字节交换

Byte swap during copy

本文关键字:字节 交换 拷贝      更新时间:2023-10-16

我需要在复制到另一个数组时有效地交换数组的字节顺序。

源数组为某一类型;Char, short或int,以便所需的字节交换是明确的,并将根据该类型进行。

我的计划是非常简单地使用多通道字节复制(简称2,4为int,…)。然而,是否有任何预先存在的"memcpy_swap_16/32/64"函数或库?可能在图像处理中用于BGR/RGB图像处理。

编辑

我知道如何交换单个值的字节,这不是问题。我想在我无论如何都要执行的复制期间执行此过程

例如,如果我有一个数组或小端序4字节整数,我可以通过执行4字节复制来交换它们,初始偏移量为0、1、2和3,步长为4。但是可能有更好的方法,也许甚至单独读取每个4字节的整数并使用字节交换特性_byteswap_ushort、_byteswap_ulong和_byteswap_uint64会更快。但是我怀疑一定有现有的函数可以做这种类型的处理。

编辑2

刚刚发现了这个,这可能是SSE的一个有用的基础,尽管内存带宽可能会浪费时间。

RGB到BGRA的快速矢量化转换

Unix系统有一个swab函数,它可以满足您对16位数组的需求。可能是优化过的,但我不确定。请注意,如果您只编写简单的字节交换代码,现代gcc将生成非常高效的代码:

uint32_t x, y;
y = (x<<24) | (x<<8 & 0xff0000) | (x>>8 & 0xff00) | (x>>24);

。它将在i486+上使用bswap指令。大概把这个放到循环中也会产生一个有效的循环…

Edit:对于您的复制任务,我会在您的循环中执行以下操作:

  1. const uint32_t *src中读取32位值
  2. 使用上面的代码进行交换
  3. uint32_t *dest写入32位值

严格地说,这可能不是可移植的(违反了混叠),但只要复制函数在自己的翻译单元中并且没有内联,就没有什么可担心的。忘掉我写的混叠吧;如果您将数据交换为32位值,那么几乎可以肯定,它实际上是从32位值开始的,而不是被强制转换的其他类型的指针,因此没有问题。

在linux中,您应该检查标题bits/byteswap.h。有一组形式为bswap_##的宏,其中一些在适当的地方使用汇编指令。

是的,存在像问题中链接的函数这样的现有函数,但它不值得努力,因为数据的大小(在这种情况下)意味着设置开销太高。因此,最好一次读取2、4和8个字节,然后使用intrinsic进行交换并回写。