我已经阅读了维基百科关于Duff's device的文章,但我还是不理解。我非常感兴趣,但我已经多次阅读了那里的解释,仍然不明白Duff's设备如何工作。
更详细的解释会是什么?
我已经阅读了维基百科关于Duff's device的文章,但我还是不理解。我非常感兴趣,但我已经多次阅读了那里的解释,仍然不明白Duff's设备如何工作。
更详细的解释会是什么?
这里是使用Duff's Device实现的64位memcpy的工作示例:
#include <iostream>
#include <memory>
inline void __memcpy(void* to, const void* from, size_t count)
{
size_t numIter = (count + 56) / 64; // gives the number of iterations; bit shift actually, not division
size_t rest = count & 63; // % 64
size_t rest7 = rest&7;
rest -= rest7;
// Duff's device with zero case handled:
switch (rest)
{
case 0: if (count < 8)
break;
do { *(((unsigned long long*&)to)++) = *(((unsigned long long*&)from)++);
case 56: *(((unsigned long long*&)to)++) = *(((unsigned long long*&)from)++);
case 48: *(((unsigned long long*&)to)++) = *(((unsigned long long*&)from)++);
case 40: *(((unsigned long long*&)to)++) = *(((unsigned long long*&)from)++);
case 32: *(((unsigned long long*&)to)++) = *(((unsigned long long*&)from)++);
case 24: *(((unsigned long long*&)to)++) = *(((unsigned long long*&)from)++);
case 16: *(((unsigned long long*&)to)++) = *(((unsigned long long*&)from)++);
case 8: *(((unsigned long long*&)to)++) = *(((unsigned long long*&)from)++);
} while (--numIter > 0);
}
switch (rest7)
{
case 7: *(((unsigned char*)to)+6) = *(((unsigned char*)from)+6);
case 6: *(((unsigned short*)to)+2) = *(((unsigned short*)from)+2); goto case4;
case 5: *(((unsigned char*)to)+4) = *(((unsigned char*)from)+4);
case 4: case4: *((unsigned long*)to) = *((unsigned long*)from); break;
case 3: *(((unsigned char*)to)+2) = *(((unsigned char*)from)+2);
case 2: *((unsigned short*)to) = *((unsigned short*)from); break;
case 1: *((unsigned char*)to) = *((unsigned char*)from);
}
}
void main()
{
static const size_t NUM = 1024;
std::unique_ptr<char[]> str1(new char[NUM+1]);
std::unique_ptr<char[]> str2(new char[NUM+1]);
for (size_t i = 0 ; i < NUM ; ++ i)
{
size_t idx = (i % 62);
if (idx < 26)
str1[i] = 'a' + idx;
else
if (idx < 52)
str1[i] = 'A' + idx - 26;
else
str1[i] = '0' + idx - 52;
}
for (size_t i = 0 ; i < NUM ; ++ i)
{
memset(str2.get(), ' ', NUM);
__memcpy(str2.get(), str1.get(), i);
if (memcmp(str1.get(), str2.get(), i) || str2[i] != ' ')
{
std::cout << "Test failed for i=" << i;
}
}
return;
}
它处理零长度情况(在原始的达夫设备中,假设num>0)。 函数main()包含了__memcpy的简单测试用例。