代码之家  ›  专栏  ›  技术社区  ›  Ryu

如何从非字节对齐的源复制内存(移位)

  •  5
  • Ryu  · 技术社区  · 14 年前

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

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

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

    谢谢

    3 回复  |  直到 14 年前
        1
  •  5
  •   RBerteig Keith Adler    14 年前

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

    你不必做字节操作,你总是可以读取源代码 long 通过在开始时最多执行三个字节,并以类似的方式处理结束,以适应大部分操作,因为您不应该试图读取超过指定的源缓冲区长度的数据。

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

    如果您在源代码中挖掘到一个压缩工具或库,它广泛使用可变宽度标记(zlib、mpeg、tiff和jpeg都是跳跃式的),那么您可能会发现将输入或输出缓冲区视为具有一些实现思想的位流的示例代码。

        2
  •  3
  •   Alexandru    14 年前

    在x86上,可以访问的最小单元是一个字节。但是,您可以一次访问4个字节,一次使用4个字节,而不是一个字节。为了提高速度,您可以使用pslldq( SSE2 )当然,要确保您的拷贝是对齐的,以获得最大的性能。

        3
  •  0
  •   Ryu    14 年前

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

    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;
    
    }