复制期间的字节交换

时间:2011-09-08 02:31:27

标签: c++ c memory

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

源数组属于某种类型; char,short或int所以所需的字节交换是明确的,并且将根据该类型。

我的计划是使用多遍字节副本(简称2,int为4,...)来做到这一点。但是有没有预先存在的“memcpy_swap_16 / 32/64”函数或库?也许在用于BGR / RGB图像处理的图像处理中。

修改

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

例如,如果我有一个数组或小端4字节整数,我可以通过执行4个字节副本进行交换,初始偏移量为0,1,2和3,步幅为4.但可能有一个更好的方法,甚至可能单独读取每个4字节整数并使用字节交换内在函数_byteswap_ushort,_byteswap_ulong和_byteswap_uint64会更快。但我怀疑必须有现有的功能才能进行这种处理。

编辑2

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

Fast vectorized conversion from RGB to BGRA

3 个答案:

答案 0 :(得分:6)

Unix系统有一个swab函数,可以为16位数组提供所需的功能。它可能已经过优化,但我不确定。请注意,如果您只是编写天真的字节交换代码,现代gcc将生成非常高效的代码:

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

即。它将在i486 +上使用bswap指令。大概将它放在一个循环中也会给出一个有效的循环......

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

  1. const uint32_t *src读取32位值。
  2. 使用上面的代码进行交换。
  3. 将32位值写入uint32_t *dest
  4. 严格来说,这可能不是可移植的(锯齿违规),但只要复制功能在自己的翻译单元中并且没有内联,就没什么可担心的。忘掉我写的内容关于别名;如果你将数据交换为32位值,它几乎肯定是32位值开始,而不是其他类型的指针,所以没有问题。

答案 1 :(得分:3)

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

答案 2 :(得分:1)

是的,现有的功能就像在问题中链接的那样,但不值得付出努力,因为数据的大小(在这种情况下)意味着设置开销太高。所以相反,最好一次读出2个,4个和8个字节,并使用内在函数进行交换并回写。