我当时正在考虑解决此问题,但看起来却是一项艰巨的任务。如果我自己一个人学习,我可能会用几种不同的方式编写它并选择最好的方法,所以我想问这个问题,看看是否有一个好的图书馆已经解决了这个问题,或者是否有人有想法/建议。

void OffsetMemCpy(u8* pDest, u8* pSrc, u8 srcBitOffset, size size)
{
    // Or something along these lines. srcBitOffset is 0-7, so the pSrc buffer
    // needs to be up to one byte longer than it would need to be in memcpy.
    // Maybe explicitly providing the end of the buffer is best.
    // Also note that pSrc has NO alignment assumptions at all.
}

我的应用程序是时间紧迫的,因此我想以最小的开销来解决这个问题。这是困难/复杂性的根源。在我的情况下,块可能很小,可能是4到12个字节,因此大规模的memcpy内容(例如prefetch)并不那么重要。最好的结果是,对于随机未对齐的src缓冲区,对于“大小”恒定的输入(4到12)最快的测试结果。
  • 内存应尽可能以字大小的块移动
  • 这些字大小的块的对齐很重要。 pSrc是未对齐的,因此我们可能需要从头读取几个字节,直到对齐为止。

  • 有人知道过类似的实现方法吗?还是有人想在编写本文时尽可能让它变得干净和高效?

    编辑:似乎人们对此投票表示“太广泛”。某些狭窄的细节可能是AMD64是首选的体系结构,因此让我们假设这一点。这意味着没有尾数等。该实现有望很好地适合一个答案的大小,因此我认为这不是太宽泛。我要求的答案是一次实现的,即使有几种方法也是如此。

    最佳答案

    我将从一个简单的实现开始,例如:

    inline void OffsetMemCpy(uint8_t* pDest, const uint8_t* pSrc, const uint8_t srcBitOffset, const size_t size)
    {
        if (srcBitOffset == 0)
        {
            for (size_t i = 0; i < size; ++i)
            {
                pDest[i] = pSrc[i];
            }
        }
        else if (size > 0)
        {
            uint8_t v0 = pSrc[0];
            for (size_t i = 0; i < size; ++i)
            {
                uint8_t v1 = pSrc[i + 1];
                pDest[i] = (v0 << srcBitOffset) | (v1 >> (CHAR_BIT - srcBitOffset));
                v0 = v1;
            }
        }
    }
    

    (警告:未经测试的代码!)。

    一旦运行正常,然后在您的应用程序中对其进行分析-您可能会发现它足够快地满足您的需求,从而避免了过早优化的陷阱。如果没有,那么您将有一个有用的基准引用实现,以进行进一步的优化工作。

    请注意,对于小型拷贝,测试对齐和字大小的拷贝等开销可能远远超过任何好处,因此,诸如上述的简单逐字节循环可能接近最佳状态。

    还请注意,优化可能完全取决于体系结构-在一个CPU上受益的微优化可能在另一个CPU上适得其反。

    关于c++ - 类似“memcpy”的功能,是否支持单个位的偏移量?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32043911/

    10-14 17:29