retweet

我的memcpy还是不如标准库的厉害,洗洗睡吧:)

CODE:
#include #include #include #ifdef WIN32 #include #else #include #include #endif double get_time_ms() { #ifdef WIN32 return (double)GetTickCount(); #else struct timeval tv; struct timezone tz; gettimeofday (&tv , &tz); return tv.tv_sec * 1000 + tv.tv_usec / 1000 ; #endif } //这是微软公开的crt src文件夹内的源代码: void * memcpy_1 (void * dst, void * src , size_t n) { void * ret = dst; while (n--) { *(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } return ret; } //这是我写的,按照最近流行的优化方式做的 void * memcpy_2 (void * dst, void * src , size_t n) { void * ret = dst; size_t l = n>>2; while (l--) { *(size_t *)dst = *(size_t *)src; dst = (size_t *)dst + 1; src = (size_t *)src + 1; } l = n & 3; while (l--) { *(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } return ret; } void main(int argc, char ** argv) { const int cstMemSize = 0x2FFFFFF; if(argc<2) { printf("请输入参数 [ 0 | 1 | 2 | 3] "); return ; } char * str = (char*)malloc(cstMemSize); char * str2 = (char*)malloc(cstMemSize+16); size_t t1 = get_time_ms(); switch(argv[1][0]) { case '0': memcpy(str, str2, cstMemSize ); break; case '1': memcpy_1(str, str2, cstMemSize ); break; case '2': memcpy_2(str, str2, cstMemSize ); break; case '3': memcpy_2(str, str2+1, cstMemSize ); //考虑字节不对齐的情况 break; } double t2 = get_time_ms(); free(str); free(str2); printf("memset_%c %f\n", argv[1][0] ,t2-t1); }
在windows xp/vc6环境下: 结果发现memcpy_1是最慢的,当然,这是串操作,当然很慢; 但是直接调用memcpy函数是最快的,这大概是微软在vc链接程序时做的优化. 而上面memcpy_2的效果一般般,比memcpy_1快,但是不如直接调用memcpy快. 在gcc/freebsd环境下,如果未加优化参数-O2,case '3'的情况速度更慢.我怀疑可能是字节不对齐带来的恶果. 不过,当开启了-O2后,4个case的测试时间差不多了.但是还是gcc自己的memset函数最快. 我现在怀疑,象(int *)这样的奇技淫巧如果使用不当,带来的效果不明显,还不如不用.现实情况是复杂的,编译器比我考虑的多的多.

--EOF--

若无特别说明,本站文章均为原创,转载请保留链接,谢谢

本文地址: http://www.dulao5.com/note/2006/12/28/my-memcpy-function.textile