关于循环展开优化的讨论

jsblcg 2004-12-07 06:19:12
/*
联系我: jsblcg@163.com
这段代码用于测试循环展开的性能,结果非常奇怪:
如果禁止编译器优化,循环展开如同一般文章所说,展开的越多性能越好,
但如果打开编译器优化(Visual C++ 6),则小于某一尺寸(256K)的数据,
循环读展开没有多大影响,大于这个尺寸的值,展开2层即可,更多的展开
不会提高多少性能
更奇怪的是循环写展开反而性能下降!

数据如下(单位是时钟周期)
机器是P4 1.0G/256M
Windows 2000 Professional
Visual C++ 6.0

禁止优化时
读:
23358907 没有展开
19442372 展开2,有提高
18489986 展开4,提高不明显
17593574 展开8
写:
21410474 有提高
19782066
19475123
19970877

打开最大速度优化:
小数据时(数据意义同上):
699698 影响不大
629779
668786
584814

142500 性能降低了!
571348
611947
675471

大数据时:
15888915
8841968 有提高
8353201
8093060

10166389 性能降低!!
19531106
20007260
19489649

谁能告诉我为什么如此?
*/

#include "stdafx.h"
#include<windows.h>

__int64 GetCounter();
void WriteTest();
void ReadTest();

#define SIZE 1024*1024

int a[SIZE];

int main(int argc, char* argv[])
{
ReadTest();
printf( "\n" );
WriteTest();
return 0;
}

void WriteTest()
{
int k;

for( k=0; k<sizeof(a)/sizeof(int); k++ )
a[k] = 0;

__int64 t1 = GetCounter();
for( k=0; k<sizeof(a)/sizeof(int); k++ )
{
a[k] = 0;
}
__int64 t2 = GetCounter();
Sleep(1000);
printf( "%I64d\n", t2 - t1 );

t1 = GetCounter();
for( k=0; k<sizeof(a)/sizeof(int); k+=2 )
{
a[k] = 0;
a[k+1] = 0;
}
t2 = GetCounter();
Sleep(1000);
printf( "%I64d\n", t2 - t1 );

t1 = GetCounter();
for( k=0; k<sizeof(a)/sizeof(int); k+=4 )
{
a[k] = 0;
a[k+1] = 0;
a[k+2] = 0;
a[k+3] = 0;
}
t2 = GetCounter();
Sleep(1000);
printf( "%I64d\n", t2 - t1 );

t1 = GetCounter();
for( k=0; k<sizeof(a)/sizeof(int); k+=8 )
{
a[k] = 0;
a[k+1] = 0;
a[k+2] = 0;
a[k+3] = 0;
a[k+4] = 0;
a[k+5] = 0;
a[k+6] = 0;
a[k+7] = 0;
}
t2 = GetCounter();
Sleep(1000);
printf( "%I64d\n", t2 - t1 );
}


void ReadTest()
{
int k, d = 0;

for( k=0; k<sizeof(a)/sizeof(int); k++ )
a[k] = 0;

__int64 t1 = GetCounter();
for( k=0; k<sizeof(a)/sizeof(int); k++ )
{
d += a[k];
}
__int64 t2 = GetCounter();
Sleep(1000);
printf( "%I64d\n", t2 - t1 );

t1 = GetCounter();
for( k=0; k<sizeof(a)/sizeof(int); k+=2 )
{
d += a[k];
d += a[k+1];
}
t2 = GetCounter();
Sleep(1000);
printf( "%I64d\n", t2 - t1 );

t1 = GetCounter();
for( k=0; k<sizeof(a)/sizeof(int); k+=4 )
{
d += a[k];
d += a[k+1];
d += a[k+2];
d += a[k+3];
}
t2 = GetCounter();
Sleep(1000);
printf( "%I64d\n", t2 - t1 );

t1 = GetCounter();
for( k=0; k<sizeof(a)/sizeof(int); k+=8 )
{
d += a[k];
d += a[k+1];
d += a[k+2];
d += a[k+3];
d += a[k+4];
d += a[k+5];
d += a[k+6];
d += a[k+7];
}
t2 = GetCounter();
Sleep(1000);
printf( "%I64d\n", t2 - t1 );
}

__declspec(naked)__int64 GetCounter()
{
__asm rdtsc
__asm ret
}

...全文
449 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
avalonBBS 2004-12-18
  • 打赏
  • 举报
回复
牵扯的方面太多了。。学习ing~~
sandrowjw 2004-12-10
  • 打赏
  • 举报
回复
展开太多的话指令会变长,不过这里主要是=0这种操作重复做的话实际上优化以后只会做一次。

还有一次测试的数据不是很准确,我曾经自己写了一个memcpy和库里的比速度,结果发觉有的时候是我快,有的时候是库里的快,但是总体上是库里的快。
blas 2004-12-09
  • 打赏
  • 举报
回复
可以试试矩阵乘法,自己写的和商业程序性能差一个数量级!
loveisbug 2004-12-09
  • 打赏
  • 举报
回复
俺现在比较关心空间性能,牺牲时间换取空间。
yjh1982 2004-12-09
  • 打赏
  • 举报
回复
在刚开始的code阶段,千万别作所谓的优化
sharkhuang 2004-12-09
  • 打赏
  • 举报
回复
深度探索c++对象模型中有句话:
对于编译器的优化到底起什么杨的作用只有实际测试才知道。
pacman2000 2004-12-08
  • 打赏
  • 举报
回复
...... 看来各个方面都有影响啊。
jsblcg 2004-12-08
  • 打赏
  • 举报
回复
问题取消,太复杂了,刚测试发现还与指令缓存有关系。
jsblcg 2004-12-08
  • 打赏
  • 举报
回复
WriteTest()中赋值不能是0,否则会被优化掉,改为:
a[k] = k;
数据有所改变,大数据时写展开有微弱的性能提高,其他问题不变,建议运行一下

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧