[C++ 学习笔记 4] Duff's Device(switch 和 for 穿插)

原创
2017/01/09 23:36
阅读数 187

看了 asio 的 \src\tests\latency\tcp_server.cpp 代码,被 coroutine 的 reenter 和 yield 的实现给震精到了……switch 和 for 穿插着,这居然也行,还有个学名叫“Duff's Device”!赶快写个测试代码,证明它是对的:

void foo(int n)
{
	printf_s("---- %d ----\n", n);
	switch (n) {
		for (;;)
	case 0:
		if (1) {
			printf_s("0\n");
			break;
		} else
	case 1:
		printf_s("1\n");
		break;
	default:
		printf_s("default\n");
		break;
	}
}

int main()
{
	foo(0);
	foo(1);
	return 0;
}

顺利编译,输出是:

---- 0 ----
0
---- 1 ----
1
0

好像不容易看懂,但是加上一些 {} 就容易了:

void foo(int n)
{
	printf_s("---- %d ----\n", n);
	switch (n) {
		for (;;) {
	case 0:
			if (1) {
				printf_s("0\n");
				break;
			} else {
	case 1:
				printf_s("1\n");
			}
		}
		break;
	default:
		printf_s("default\n");
		break;
	}
}

大神的代码不容置疑,以下代码追求减少循环测试的执行次数。

void duff_memcpy(char* to, char* from, size_t count)
{
	size_t n = (count + 7) / 8;
	switch (count % 8) {
	case 0: do { *to++ = *from++;
	case 7: *to++ = *from++;
	case 6: *to++ = *from++;
	case 5: *to++ = *from++;
	case 4: *to++ = *from++;
	case 3: *to++ = *from++;
	case 2: *to++ = *from++;
	case 1: *to++ = *from++;
	} while (--n > 0);
	}
}

第一轮用 switch 选择进入点,以后每轮都是复制 8 字节。

扩展阅读:

《Asio 协程详解》https://www.avboost.com/t/asio/771

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
1 收藏
0
分享
返回顶部
顶部