- //目的:企图定位ARM-Linux下程序运行速度缓慢的原因。
- // TYPE, 缓冲区的操作类型(比较同样的运算规模下int8, int16, int32的执行速度差异)
- //
- // buf, 一个大小为SIZE*2(Bytes)的缓冲区
- // SIZE, 实际进行操作的缓冲区的尺寸(Bytes)(比较运算规模线性增长时,执行速度是否线性下降)
- // SPAN, 内层循环的尺寸(Bytes)(查看内层循环的规模变化时,执行速度是否有变化)
- //
- // [备注:实验的结果表明SPAN的变化会显著影响程序的执行效率]
- template<class TYPE>void buff_access(void *buf, int SIZE, int SPAN)
- {
- int xx = SPAN/sizeof(TYPE); //内层循环规模
- int yy = (SIZE/SPAN); //外层循环规模(计算规模=对一个(SIZE)bytes缓冲区写入一遍)
- long tm; //计时用变量
- if((xx*yy*sizeof(TYPE)) != (unsigned int)SIZE) return; //保证在调整SPAN的大小时,计算规模不变
- TYPE (*theBuf)[xx] = (TYPE (*)[xx])(buf); //将传入的缓冲区转换为二维数组形式
- int i, j, k;
- int *p = new int[xx]; //模拟对缓冲区随机操作的一维缓冲区(里面填入[0,xx]的随机值)
- volatile int *pos; //随机操作模拟缓冲区读指针
- for(i = 0; i<xx;++i) //随机操作模拟缓冲区初始化,您现在看到的版本是修改后的,缓冲区内容全为0
- {
- (i%2) ?
- p[i] = 0 : p[i] = 0;
- }
- SetTimeMark(tm); //计时开始
- for(k = 0; k<LOOP_TIMES; ++k) //延长执行的时间
- {
- for(i = 0; i<yy; ++i) //外层循环(二维缓冲区行)
- {
- pos = p; //随机操作模拟缓冲区读指针复位
- for(j = 0; j<xx; ++j) //内循环(二维缓冲区列)
- {
- theBuf[i][*pos] = 0; //模拟刷新当前行,随机列的内容
- ++pos; //变换列索引
- }
- }
- }
- long totalTime = GetElapseTime(tm); //计时结束
- TraceAndLog("performance.log",
- "方法:%s/n用时:%ld(us)/n缓冲区长:%d(KB)/n内层循环长:%f(KB)/n单元:%d(B)/n实际长度:%d(KB)/n",
- "二维数组-刷新",
- totalTime,
- SIZE/1024,
- ((float)SPAN)/1024,
- sizeof(TYPE),
- (yy*xx*sizeof(TYPE))/1024
- );
- delete[] p;
- }
在ARM(S3c2440), linux2.6.13上的执行结果:
SIZE = 1024*1024(1M Bytes), LOOP_TIMES = 10;
内循环尺寸(Bytes) | 运行时间(us) |
1K | 104580 |
2K | 93221 |
... | ... |
32K | 321554 |