我正在使用gettimeofday()
来计算一个简单的矩阵乘法示例,但我得到的结果最近接近两倍。在RHEL6服务器计算机上,我得到的“坏”计时结果长达近1秒(在此示例中约为65个单独计时)。我们所有的其他机器都是RHEL5工作站盒子,这些代码可以更好地工作很多;我最初只得到几个“坏”结果(第一个~20毫秒)。
从本网站的帖子来看,我认为这可能与操作系统进程调度程序有关。如果我取消注释下面的第一个“for”语句(从而通过重复初始化矩阵a,b和c插入一个初始忙循环),我在RHEL5 Workstation和RHEL6 Server下得到零“坏”结果。或者,如果我取消注释睡眠声明,我会得到RHEL5&的所有“坏”时序结果。 RHEL6。
出于某种原因,我的进程最初启动时只有大约一半的CPU访问权限,只要进程保持繁忙,它就会“完全”访问CPU。如果它“休眠”然后恢复计时,它再次暂时只能获得大约一半的CPU访问权。
机器上没有其他任何事情发生(X未运行)。我试过“chrt”来控制进程的优先级,但是没有改变。我已经用GCC 4.4.6和ICC 12.1.0验证了这种情况。我也试过“很好”。
以下是代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#define N 225
#define DELAY_LOOPS 8000
main() {
struct timeval _t0, _t1, _t2;
double a[N][N], b[N][N], c[N][N];
double millisec, cum_ms;
int i, j, k, l, m=0;
gettimeofday( &_t0, NULL );
// for( l=0; l<DELAY_LOOPS; l++ )
for( i=0; i<N; i++ )
for( j=0; j<N; j++ ) {
a[i][j]=0;
b[i][j]=i;
c[i][j]=j;
}
for( l=0; l<75; l++ ) {
gettimeofday( &_t1, NULL );
for( i=0; i<N; i++ )
for( j=0; j<N; j++ )
for( k=0; k<N; k++ )
a[i][j]+=b[i][k]*c[k][j];
gettimeofday( &_t2, NULL );
millisec = 1000*(_t2.tv_sec-_t1.tv_sec);
millisec += 1e-3*(_t2.tv_usec-_t1.tv_usec);
cum_ms = 1000*(_t2.tv_sec-_t0.tv_sec);
cum_ms += 1e-3*(_t2.tv_usec-_t0.tv_usec);
printf( "%d: duration %fms, cumulative %fms\n",
m++, millisec, cum_ms );
// sleep( 2 );
}
printf( "a[%d][%d]=%f\n", N/2, N/2, a[N/2][N/2] );
}
以下是结果:
% icc -O2 -o test main.c; ./test
0: duration 13.049000ms, cumulative 13.677000ms
1: duration 13.026000ms, cumulative 26.753000ms
2: duration 12.911000ms, cumulative 39.668000ms
3: duration 12.913000ms, cumulative 52.584000ms
4: duration 12.914000ms, cumulative 65.501000ms
5: duration 12.911000ms, cumulative 78.415000ms
6: duration 12.912000ms, cumulative 91.331000ms
/* snip */
64: duration 12.912000ms, cumulative 840.633000ms
65: duration 10.455000ms, cumulative 851.092000ms
66: duration 5.910000ms, cumulative 857.004000ms
67: duration 5.908000ms, cumulative 862.914000ms
68: duration 5.907000ms, cumulative 868.823000ms
69: duration 5.908000ms, cumulative 874.732000ms
70: duration 5.912000ms, cumulative 880.646000ms
71: duration 5.907000ms, cumulative 886.554000ms
72: duration 5.907000ms, cumulative 892.462000ms
73: duration 5.908000ms, cumulative 898.372000ms
74: duration 5.908000ms, cumulative 904.281000ms
a[112][112]=211680000.000000
无论优化级别如何(-O0,-O1,-O2等),我都会遇到问题。
有没有人知道如何在RHEL6服务器下完成调度?它与RHEL5工作站有很大不同吗?我认为我看到的差异更多的是这样一个事实,即一个盒子是RHEL的服务器版本,另一个是工作站版本(而不是版本5与6之间的差异)。是否有一些简单的方法可以减少RHEL6 Server下的这种影响并使其更像RHEL5 Workstation框?
有什么想法吗?感谢。
答案 0 :(得分:4)
请勿使用gettimeofday(2)
进行效果衡量。它太慢了,根本不适合这项工作。
请改用clock_gettime(2)
。它允许您从众多系统定义的定时器中选择一个。 CLOCK_REALTIME是最简单的选择,但如果你有CLOCK_PROCESS_CPUTIME_ID可能会更好。
答案 1 :(得分:2)
处理器能否进入低功耗状态?像powertop这样的东西可以告诉你。 (在频率属性标签中)