간단한 행렬 곱하기 예제를 사용하기 위해 gettimeofday()
을 사용하고 있는데, 처음에는 두 배 가까이에 결과가 나타납니다. RHEL6 서버 시스템에서, "나쁜"타이밍 결과가 최대 1 초 동안 발생합니다 (이 예에서는 ~ 65 개별 타이밍). 우리의 다른 모든 머신은 RHEL5 워크 스테이션 박스이며이 코드는 보다 우수합니다. 나는 초기에 단지 2 개의 "나쁜"결과만을 얻는다 (처음 20 밀리 초 동안).gettimeofday를 사용한 초기 타이밍 결과가 느림 - RHEL6 서버에서 악화됨
이 사이트의 게시물을 보면 아마도 OS 프로세스 스케줄러와 관련이 있다고 생각합니다. 아래의 첫 번째 "for"구문의 주석을 제거하면 (즉, 행렬 a, b 및 c를 반복적으로 초기화하여 초기 사용 중 루프를 삽입 함) RHEL5 Workstation 및 RHEL6 Server 모두에서 "불량"결과가 0이됩니다. 또는 sleep 문을 주석 처리하지 않으면 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]);
}
여기가 그 결과 다음과 같습니다 :
여기 코드의 I에 관계없이 최적화 레벨 (-O0, -O1, -O2, 등)의 문제가 발생
% 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
.
누군가 RHEL6 서버에서 스케줄링이 수행되는 방법에 대해 알고 있습니까? RHEL5 워크 스테이션과 매우 다른가요? 나는 하나의 박스가 RHEL의 서버 에디션이고 다른 하나는 워크 스테이션 에디션 (릴리스 5와 6의 차이보다는)이라는 사실에 더 많은 차이가 있다고 생각한다. RHEL6 서버에서이 효과를 줄이고 RHEL5 워크 스테이션 상자처럼 작동시키는 간단한 방법이 있습니까?
아이디어가 있으십니까? 감사.
은 서버가 과도하게 컨텍스트를 전환해야하기 때문일 수 있습니다. 계산이 끝났지 만'gettimeofday()'는 이후에 호출되는 상황을 초래합니다. 그냥 내 $ 0.02 –
당신은 전용 서버를 사용하고 있습니다. –
두 서버에서 동일한 JVM입니까? – fge