OpenMP를 사용한다고해서 프로그램이 더 빨리 실행되는 것은 아닙니다. 각 스레드를 산란에 관련된 비용이 있습니다
하고있는 경우 계산의 작은 금액 자체가 더 많은 시간이 걸릴 것입니다 스레드의 산란을 할 수있는 스레드를 생성 : 몇 가지 여기 일이 될 수있다 계산보다.
기본적으로 OpenMP는 CPU에서 지원하는 최대 스레드 수를 생성합니다. 코어 당 2 개 이상의 스레드를 지원하는 CPU를 사용하면 각 코어의 리소스에 대해 스레드가 경쟁하게됩니다. omp_get_num_threads()
을 사용하면 기본적으로 생성 될 스레드 수를 확인할 수 있습니다. omp_set_num_threads()
을 사용하여 값의 절반으로 코드를 실행하는 것이 좋습니다.
결과가 OpenMP를 사용하거나 사용하지 않았 음을 확인 했습니까? 변수 j 및 c2와의 종속성이있는 것 같습니다. 각 스레드에 개인 선언해야합니다 : 어떤 병렬화를 시도하기 전에, 당신은 코드가 이미 최적화되어 있는지 확인해야합니다 :
#pragma omp parallel for private(j,c2)
내가 다른 일을 추가하고 싶었다.
는 컴파일러, 컴파일러 플래그 및 명령의 복잡도에 따라, 컴파일러 또는 코드를 최적화하지 않을 수 있습니다 : 그것은 많이 보이지 않을 수도
// avoid calculation nnoib-2 every iteration
int t_nnoib = nnoib - 2;
for (i=2; i< t_nnoib; ++i){
// avoid calculation nnojb-2 every iteration
int t_nnojb = nnojb - 2;
// avoid loading absi[i] every iteration
int t_absi = absi[i];
for (j=2; j< t_nnojb; ++j) {
C[i][j]= t_absi * absj[j] *
(2.0f*B[i][j] + t_absi * absj[j] *
(VEL[i][j] * VEL[i][j] * fat *
(16.0f * (B[i][j-1] + B[i][j+1] + B[i-1][j] + B[i+1][j])
-1.0f * (B[i][j-2] + B[i][j+2] + B[i-2][j] + B[i+2][j])
-60.0f * B[i][j]
) - A[i][j]));
// c2 is a useless variable
if (abs(C[i][j]) > Amax[i][j]) {
Amax[i][j] = abs(C[i][j]);
Ttra[i][j] = t;
}
}
}
를, 그러나에 큰 영향을 미칠 수 있습니다 암호. 컴파일러는 레지스터에 로컬 변수를 배치하려고 시도합니다 (액세스 시간이 훨씬 빠름). 제한된 수의 레지스터가 있기 때문에 무기한으로이 기술을 적용 할 수 없으며이를 악용하면 코드가 레지스터 누출로 고통받을 수 있습니다.
absi
어레이의 경우 j
루프를 실행하는 동안 시스템이 해당 어레이 조각을 캐시에 보관하지 않아도됩니다. 이 기법의 일반적인 개념은 내부 루프의 변수에 의존하지 않는 모든 배열 액세스를 외부 루프로 이동하는 것입니다. 크리스티아누 언급 비용 외에도
'c2'는 어디에 선언 되었습니까? – Mysticial
c2는 전역 변수입니다. c2는 int입니다. 감사! –
그런 다음 'c2'에 대한 경쟁 조건/종속성이 있기 때문에 로컬로 만듭니다. – Mysticial