2013-03-08 11 views
48

Tôi đã xem xét các định nghĩa chính thức, nhưng tôi vẫn còn khá bối rối.Làm thế nào là firstprivate và lastprivate khác với các điều khoản riêng trong OpenMP?

firstprivate: Chỉ định rằng mỗi chuỗi phải có phiên bản biến riêng, và biến phải được khởi tạo bằng giá trị của biến, bởi vì nó tồn tại trước cấu trúc song song.

Với tôi, điều đó nghe có vẻ rất riêng tư. Tôi đã tìm kiếm các ví dụ, nhưng tôi dường như không hiểu làm thế nào nó đặc biệt hoặc làm thế nào nó có thể được sử dụng.

lastprivate: Chỉ định rằng phiên bản bối cảnh kèm theo của các biến được đặt tương ứng với phiên bản riêng của bất cứ thread thực thi lặp thức (đối với vòng lặp cấu trúc) hoặc phần cuối (phần #pragma).

Tôi cảm thấy như tôi hiểu cái này tốt hơn một chút vì ví dụ sau:

#pragma omp parallel 
{ 
    #pragma omp for lastprivate(i) 
     for (i=0; i<n-1; i++) 
     a[i] = b[i] + b[i+1]; 
} 
a[i]=b[i]; 

Vì vậy, trong ví dụ này, tôi hiểu rằng lastprivate cho phép i để được trả lại bên ngoài vòng lặp như giá trị cuối cùng.

Tôi mới bắt đầu học OpenMP ngay hôm nay.

Trả lời

103

private biến không được khởi tạo, tức là chúng bắt đầu với các giá trị ngẫu nhiên như bất kỳ biến tự động cục bộ nào khác (và chúng thường được thực hiện bằng cách sử dụng biến tự động trên ngăn xếp của mỗi chuỗi). Hãy chương trình đơn giản này là một ví dụ:

#include <stdio.h> 
#include <omp.h> 

int main (void) 
{ 
    int i = 10; 

    #pragma omp parallel private(i) 
    { 
     printf("thread %d: i = %d\n", omp_get_thread_num(), i); 
     i = 1000 + omp_get_thread_num(); 
    } 

    printf("i = %d\n", i); 

    return 0; 
} 

Với bốn đề nó ra cái gì đó như:

thread 0: i = 0 
thread 3: i = 32717 
thread 1: i = 32717 
thread 2: i = 1 
i = 10 

(another run of the same program) 

thread 2: i = 1 
thread 1: i = 1 
thread 0: i = 0 
thread 3: i = 32657 
i = 10 

này cho thấy rõ ràng rằng giá trị của i là ngẫu nhiên (không được khởi tạo) bên trong khu vực song song và bất kỳ sửa đổi nào đối với nó không hiển thị sau vùng song song (tức là biến giữ giá trị của nó từ trước khi vào vùng).

Nếu i được làm firstprivate, sau đó nó được khởi tạo với giá trị mà nó có trước khi khu vực song song:

thread 2: i = 10 
thread 0: i = 10 
thread 3: i = 10 
thread 1: i = 10 
i = 10 

Tuy nhiên thay đổi với giá trị của i bên trong khu vực song song là không thể nhìn thấy sau khi nó.

Bạn đã biết về lastprivate (và nó không áp dụng cho chương trình trình diễn đơn giản vì thiếu cấu trúc bảng tính).

Vì vậy, có, firstprivatelastprivate chỉ là trường hợp đặc biệt là private. Kết quả đầu tiên đưa các giá trị từ bối cảnh bên ngoài vào vùng song song trong khi giá trị thứ hai chuyển các giá trị từ vùng song song sang bối cảnh bên ngoài. Lý do đằng sau các lớp chia sẻ dữ liệu này là bên trong vùng song song tất cả các biến riêng tư che giấu các biến từ ngữ cảnh bên ngoài, tức là không thể sử dụng phép gán để sửa đổi giá trị ngoài của i từ bên trong vùng song song.

+1

Đây là một câu trả lời tuyệt vời! Cảm ơn nhiều! – SaiyanGirl

+0

Vâng, tôi muốn nói, 'firstprivate' và' lastprivate' là những trường hợp đặc biệt của 'private'. Bạn thường không cần sử dụng 'private' (chỉ định nghĩa biến bên trong khối song song), có thể che khuất phạm vi bên ngoài. Thú vị là việc sử dụng các đối tượng C++ như các biến 'firstprivate' tự động - chúng sẽ được khởi tạo thông qua sao chép, xây dựng, một lần và bị phá hủy sau khối, và bạn không cần phải biết số lượng luồng trước - nhiều bản sao sẽ được tạo khi cần. –

+0

Ví dụ tuyệt vời như vậy! Thích nhất. Đánh giá cao Hristo. – Fusionmate

1

firstprivatelastprivate chỉ là trường hợp đặc biệt là private.

Kết quả đầu tiên đưa giá trị từ ngữ cảnh bên ngoài vào vùng song song trong khi giá trị thứ hai chuyển giá trị từ vùng song song sang ngữ cảnh bên ngoài.

+0

bạn có thể cung cấp bất kỳ tài liệu tham khảo về nó? –

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