我当时正在考虑解决此问题,但看起来却是一项艰巨的任务。如果我自己一个人学习,我可能会用几种不同的方式编写它并选择最好的方法,所以我想问这个问题,看看是否有一个好的图书馆已经解决了这个问题,或者是否有人有想法/建议。
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)最快的测试结果。
有人知道过类似的实现方法吗?还是有人想在编写本文时尽可能让它变得干净和高效?
编辑:似乎人们对此投票表示“太广泛”。某些狭窄的细节可能是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/