2011-12-01 37 views
7

Tôi đang làm việc với OpenMP parallelize một vô hướng lồng vòng lặp for:Làm thế nào để parallelize một cách chính xác một lồng nhau cho vòng

double P[N][N]; 
double x=0.0,y=0.0; 

for (int i=0; i<N; i++) 
{ 
    for (int j=0; j<N; j++) 
    { 
     P[i][j]=someLongFunction(x,y); 
     y+=1; 
    } 
    x+=1; 
} 

Trong vòng này, điều quan trọng là ma trận P phải giống nhau ở cả hai vô hướng và phiên bản song song:

Tất cả các thử nghiệm khả năng của tôi đã không thành công ...

Trả lời

13

vấn đề ở đây là bạn đã thêm lặp-to-lặp phụ thuộc với:

x+=1; 
y+=1; 

Vì vậy, vì mã hiện đang đứng, nó không thể song song. Cố gắng làm như vậy sẽ dẫn đến kết quả không chính xác. (Như bạn có lẽ thấy)

May mắn thay, trong trường hợp của bạn, bạn có thể trực tiếp tính toán chúng mà không cần giới thiệu sự phụ thuộc này:

for (int i=0; i<N; i++) 
{ 
    for (int j=0; j<N; j++) 
    { 
     P[i][j]=someLongFunction((double)i, (double)N*i + j); 
    } 
} 

Bây giờ bạn có thể thử ném một OpenMP pragma trên này và xem nếu nó hoạt động:

#pragma omp parallel for 
for (int i=0; i<N; i++) 
{ 
    for (int j=0; j<N; j++) 
    { 
     P[i][j]=someLongFunction((double)i, (double)N*i + j); 
    } 
} 
+0

Ok cảm ơn câu trả lời. Tôi có thể hỏi bạn một câu hỏi khác không? Nếu tôi muốn đặt lại mỗi lần y = 0 trước vòng lặp bên trong thì sao? Thay đổi triển khai openmp sẽ như thế nào? – linello

+0

Sau đó thay đổi '(double) N * i + j' thành' (double) j'. Chìa khóa ở đây là tôi thu được các biểu thức cho 'x' và' y' như một hàm của các chỉ số vòng lặp. Điều này cho phép bạn phá vỡ các phụ thuộc. – Mysticial

+0

Rất cám ơn câu trả lời của bạn, họ đã làm rõ cho tôi cách tháo gỡ các vòng lặp để chuẩn bị cho việc song song OpenMP. Câu hỏi cuối cùng, tại sao các phiên bản nối tiếp và song song của mã này cho tôi một phần rất nhỏ các yếu tố khác nhau? 'for (int i = 0; i linello

Các vấn đề liên quan