【问题标题】:How to copy memory from source thats not on byte alignment (shifted)如何从不在字节对齐的源中复制内存(移位)
【发布时间】:2011-04-13 22:00:02
【问题描述】:

我可以想到一些令人讨厌的低效方法来完成这项任务,但我想知道最好的方法是什么。

例如,我想从一个字节的第 3 位开始复制 10 个字节,然后像往常一样复制到一个指针。

有没有比一次复制一个移位字节更好的方法?

谢谢

【问题讨论】:

  • 是@SamB 所说的。我正在使用低内存系统,并获得了一些紧凑的数据。即使没有意义,我仍然想问这个问题。
  • 看看这个非常相似的问题stackoverflow.com/questions/3534535/…
  • @nategoose 谢谢!我试图搜索这个问题是否已经被问过但找不到任何东西

标签: c memory memcpy


【解决方案1】:

这是我编写并开始使用的解决方案。

void RightShiftMemCopy(uchar * pSource, uchar * pDest ,ushort len,uchar shiftOffset)
{
    ushort i=0;

    pDest+=(len-1);
    pSource+=(len-1);

    for(i=len-1;i != 0 ;--i)
    {
        *pDest = (*(pSource - 1) << 8 | *pSource) >> shiftOffset;

        --pDest;
        --pSource;
    }

    *pDest = *pSource >> shiftOffset;

}

【讨论】:

  • 不要调用memcpy()复制一个字节。只需说destData[i] = val。您在这里使用pSource 是一个糟糕的名称选择。并且它在 memcpy 调用中的使用假定了特定的字节顺序。
【解决方案2】:

在 x86 上,您可以访问的最小单位是一个字节。但是,您一次可以访问 4 个字节并一次使用 4 个字节而不是一个字节。要获得更高的速度,您可以使用 pslldq (SSE2)。当然,请确保您的副本对齐以获得最佳性能。

【讨论】:

  • 与提问者的要求无关。他想复制具有子字节对齐的数据,你只是告诉他如何实现比他已经拥有的更糟糕的memcpy
  • @SamB:不是真的。一次移动整个单词比一次移动一个字节要快得多。
  • 是的 - @R 是对的。快了很多。您可以查看每条指令的周期。伙计们,我们不要妄下结论。
【解决方案3】:

一般的做法是尽可能高效地读取源缓冲区,并在写入目标缓冲区的过程中根据需要移动它。

您不必进行字节操作,您始终可以通过在开头最多执行三个字节来使源读取 long 与大部分操作对齐,并且类似地处理结尾,因为您不应该尝试读取超过规定的源缓冲区长度。

从读取的值中,您可以根据需要进行移位以获得所需的位对齐并组装完成的字节以写入目标。您还可以对写入的最宽对齐字长进行相同的优化。

如果您在源代码中挖掘广泛使用可变宽度标记(zlib、MPEG、TIFF 和 JPEG)的压缩工具或库,您可能会发现处理输入或输出缓冲区作为比特流,需要考虑一些实现思路。

【讨论】:

    猜你喜欢
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 2021-01-14
    • 2018-05-29
    • 2016-12-19
    • 2015-02-14
    • 1970-01-01
    相关资源
    最近更新 更多