Duff's device(Cサイクル展開)
2642 ワード
Duff's deviceは実際にはループ展開でプログラム効率を向上させる方法であり、ループ展開はCPUリソースを有効に利用して効率を向上させることができる.
次にDuff's deviceについて説明します.copyを20バイトと仮定します.
次に、汎用的なDuff's deviceと、その呼び出しを示します.
次の呼び出しコードではDuff's deviceの魅力が尽きません.
次にDuff's deviceについて説明します.copyを20バイトと仮定します.
int count; // Set to 20
{
int n = (count + 7) / 8; // n is now 3. (The "while" is going
// to be run three times.)
switch (count % 8) { // The remainder is 4 (20 modulo 8) so
// jump to the case 4
case 0: // [skipped]
do { // [skipped]
*to = *from++; // [skipped]
case 7: *to = *from++; // [skipped]
case 6: *to = *from++; // [skipped]
case 5: *to = *from++; // [skipped]
case 4: *to = *from++; // Start here. Copy 1 byte (total 1)
case 3: *to = *from++; // Copy 1 byte (total 2)
case 2: *to = *from++; // Copy 1 byte (total 3)
case 1: *to = *from++; // Copy 1 byte (total 4)
} while (--n > 0); // N = 3 Reduce N by 1, then jump up
// to the "do" if it's still
} // greater than 0 (and it is)
}
次に、汎用的なDuff's deviceと、その呼び出しを示します.
#define DUFF_DEVICE_8(aCount, aAction) \
do { \
int count_ = (aCount); \
int times_ = (count_ + 7) >> 3; \
switch (count_ & 7){ \
case 0: do { aAction; \
case 7: aAction; \
case 6: aAction; \
case 5: aAction; \
case 4: aAction; \
case 3: aAction; \
case 2: aAction; \
case 1: aAction; \
} while (--times_ > 0); \
} \
} while (0)
次の呼び出しコードではDuff's deviceの魅力が尽きません.
int CopyToEEPROM(const void* pSource, void* pDest, unsigned len) { // Anything to copy? if (len > 0) { const char* s = (const char*)pSource; char* d = (char*)pDest; // First, need to copy data to page buffer DUFF_DEVICE_8(len, *d++ = *s++); // Start EEPROM write cycle HAL_EEPROM_WRITE(); // Check if data was transferred correctly s = (const char*)pSource; d = (char*)pDest; DUFF_DEVICE_8(len, if (*d++ != *s++) return 1; /* Fail */); } return 0; // Success }
http://www.drdobbs.com/a-reusable-duff-device/184406208