Tôi mới ở đây và một lập trình viên mới bắt đầu ở C. Tôi đang gặp một số vấn đề khi sử dụng openmp để tăng tốc cho vòng lặp. Dưới đây là ví dụ đơn giản:OpenMP và C song song cho vòng lặp: tại sao mã của tôi làm chậm khi sử dụng OpenMP?
#include <stdlib.h>
#include <stdio.h>
#include <gsl/gsl_rng.h>
#include <omp.h>
gsl_rng *rng;
main()
{
int i, M=100000000;
double tmp;
/* initialize RNG */
gsl_rng_env_setup();
rng = gsl_rng_alloc (gsl_rng_taus);
gsl_rng_set (rng,(unsigned long int)791526599);
// option 1: parallel
#pragma omp parallel for default(shared) private(i, tmp) schedule(dynamic)
for(i=0;i<=M-1;i++){
tmp=gsl_ran_gamma_mt(rng, 4, 1./3);
}
// option 2: sequential
for(i=0;i<=M-1;i++){
tmp=gsl_ran_gamma_mt(rng, 4, 1./3);
}
}
Mã rút ra từ phân phối ngẫu nhiên gamma cho các lần lặp M. Nó chỉ ra cách tiếp cận song song với openmp (tùy chọn 1) mất khoảng 1 phút trong khi phương pháp tiếp cận tuần tự (tùy chọn 2) chỉ mất 20 giây. Trong khi chạy với openmp, tôi có thể thấy việc sử dụng CPU là 800% (máy chủ tôi đang sử dụng có 8 CPU). Và hệ thống này là Linux với GCC 4.1.3. Lệnh biên dịch tôi đang sử dụng là gcc -fopenmp -lgsl -lgslcblas -lm (Tôi đang sử dụng GSL)
Tôi có làm gì sai không? Làm ơn giúp tôi! Cảm ơn!
P.S. Như được chỉ ra bởi một số người dùng, nó có thể được gây ra bởi rng. Nhưng ngay cả khi tôi thay
tmp=gsl_ran_gamma_mt(rng, 4, 1./3);
bởi nói
tmp=1000*10000;
vấn đề vẫn còn đó ...
Bạn không nên biến biến vòng lặp của mình thành riêng tư - OpenMP sẽ xử lý điều đó. Tôi không biết nếu điều này ảnh hưởng đến việc thực hiện, nhưng bạn nên sửa chữa nó và kiểm tra lại. –
Ngoài ra, lưu ý rằng tmp = 1000 * 10000 có thể được tối ưu hóa bởi trình biên dịch thành một vòng, do đó sẽ làm lệch thời gian của bạn. –
Bạn có chắc chắn thực sự có 8 CPU không? Nó có thể là một quad-core với hyperthreading? –