omp song song so với omp song song cho


105

sự khác biệt giữa hai cái đó là gì?

[A]

#pragma omp parallel
{ 
    #pragma omp for
    for(int i = 1; i < 100; ++i)
    {
        ...
    }
}

[B]

#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
   ...
}

Câu trả lời:


65

Tôi không nghĩ rằng có bất kỳ sự khác biệt nào, một cái là lối tắt cho cái kia. Mặc dù việc triển khai chính xác của bạn có thể giải quyết chúng theo cách khác.

Các cấu trúc chia sẻ công việc song song kết hợp là một lối tắt để chỉ định một cấu trúc song song chứa một cấu trúc chia sẻ công việc và không có câu lệnh nào khác. Các mệnh đề được phép là sự kết hợp của các mệnh đề được phép đối với các cấu trúc chia sẻ công việc và song song.

Lấy từ http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf

Các thông số kỹ thuật cho OpenMP ở đây:

https://openmp.org/specification/


66

Chúng tương đương nhau.

#pragma omp parallelsinh ra một nhóm các chủ đề, trong khi #pragma omp forphân chia các lần lặp vòng lặp giữa các chủ đề được tạo ra. Bạn có thể làm cả hai việc cùng một lúc với #pragma omp parallel forchỉ thị hợp nhất .


Trong mã của tôi, tôi đang sử dụng chính cấu trúc này. Tuy nhiên, khi tôi sử dụng schedule(static, chunk)mệnh đề trong chỉ thị, tôi gặp vấn đề. Mã chạy tốt nhưng khi tôi gọi mã này từ một chương trình MPI thì nó chạy vào một vòng lặp vô hạn. Bộ đếm vòng lặp bằng 0 trong tất cả các lần lặp của vòng lặp này. Tôi có bộ đếm vòng lặp được xác định là riêng tư trong #pragma omp parallelchỉ thị. Không hiểu tại sao nó chỉ không thành công khi Bộ KH & ĐT đang gọi mã. Tôi chắc chắn rằng mỗi quy trình MPI đang chạy trên một bộ xử lý khác nhau của cụm nếu điều đó quan trọng. Không biết liệu lịch trình có gây ra sự cố hay không.
Rohit Banga

Điều tương tự cũng hoạt động tốt khi tôi sử dụng #pragma omp parallel forchỉ thị. Phải có một số khác biệt.
Rohit Banga

1
Cập nhật: Hóa ra, tôi chỉ quan sát thấy vấn đề này khi tôi sử dụng mệnh đề lịch trình vì vậy tôi đoán nó không phụ thuộc vào việc tôi sử dụng song song kết hợp cho hay hai chỉ thị khác nhau.
Rohit Banga

28

Đây là ví dụ về việc sử dụng phân tách parallelfor đây . Tóm lại, nó có thể được sử dụng để phân bổ động các mảng luồng riêng tư OpenMP trước khi thực hiện forchu trình trong một số luồng. Không thể thực hiện việc khởi tạo tương tự trong parallel fortrường hợp.

UPD: Trong ví dụ câu hỏi không có sự khác biệt giữa pragma đơn và pragma hai. Nhưng trong thực tế, bạn có thể thực hiện nhiều hành vi nhận biết luồng hơn với các lệnh song song và cho các chỉ thị được phân tách. Một số mã ví dụ:

#pragma omp parallel
{ 
    double *data = (double*)malloc(...); // this data is thread private

    #pragma omp for
    for(1...100) // first parallelized cycle
    {
    }

    #pragma omp single 
    {} // make some single thread processing

    #pragma omp for // second parallelized cycle
    for(1...100)
    {
    }

    #pragma omp single 
    {} // make some single thread processing again

    free(data); // free thread private data
}

9

Mặc dù cả hai phiên bản của ví dụ cụ thể là tương đương, như đã được đề cập trong các câu trả lời khác, vẫn có một sự khác biệt nhỏ giữa chúng. Phiên bản đầu tiên bao gồm một rào cản ngầm không cần thiết, gặp phải ở cuối "omp for". Rào cản ngầm khác có thể được tìm thấy ở cuối vùng song song. Thêm "nowait" vào "omp for" sẽ làm cho hai mã tương đương nhau, ít nhất là từ góc độ OpenMP. Tôi đề cập đến điều này vì trình biên dịch OpenMP có thể tạo ra mã hơi khác nhau cho hai trường hợp.


7

Tôi thấy thời gian chạy hoàn toàn khác khi tôi thực hiện một vòng lặp for trong g ++ 4.7.0 và sử dụng

std::vector<double> x;
std::vector<double> y;
std::vector<double> prod;

for (int i = 0; i < 5000000; i++)
{
   double r1 = ((double)rand() / double(RAND_MAX)) * 5;
   double r2 = ((double)rand() / double(RAND_MAX)) * 5;
   x.push_back(r1);
   y.push_back(r2);
}

int sz = x.size();

#pragma omp parallel for

for (int i = 0; i< sz; i++)
   prod[i] = x[i] * y[i];

mã nối tiếp (không openmp) chạy trong 79 ms. mã "song song cho" chạy trong 29 ms. Nếu tôi bỏ qua forvà sử dụng #pragma omp parallel, thời gian chạy sẽ lên đến 179ms, chậm hơn so với mã nối tiếp. (máy có đồng thời hw là 8)

mã liên kết đến libgomp


2
tôi nghĩ đó là do omp song song thực hiện vòng lặp trong luồng riêng biệt mà không chia nó thành các luồng, vì vậy luồng chính đang chờ luồng thứ hai kết thúc. và dành thời gian để đồng bộ hóa.
Antigluk

7
Đó là bởi vì không có một #pragma omp forvòng lặp chia sẻ đa luồng. Nhưng đó không phải là trường hợp OPs, hãy thử lại với một phần bổ sung #pragma omp forbên trong #pragm omp parallelvà nó sẽ chạy tương tự (nếu không giống) như #pragma omp parallel forphiên bản.
Christian Rau

2
Tôi thấy câu trả lời này là một trong những tốt nhất vì nó cho thấy họ không phải là "tương đương"
Không Scientist

6

Rõ ràng là có rất nhiều câu trả lời, nhưng câu trả lời này rất hay (có nguồn)

#pragma omp forchỉ ủy quyền các phần của vòng lặp cho các luồng khác nhau trong nhóm hiện tại. Một nhóm là nhóm các luồng thực thi chương trình. Khi bắt đầu chương trình, nhóm chỉ bao gồm một thành viên duy nhất: luồng chủ chạy chương trình.

Để tạo một nhóm chủ đề mới, bạn cần chỉ định từ khóa song song. Nó có thể được chỉ định trong bối cảnh xung quanh:

#pragma omp parallel
{
   #pragma omp for
   for(int n = 0; n < 10; ++n)
   printf(" %d", n);
}

và:

Là gì: song song, cho và một nhóm

Sự khác biệt giữa song song, song song cho và cho như sau:

Nhóm là nhóm các chủ đề hiện đang thực thi. Khi bắt đầu chương trình, nhóm bao gồm một chủ đề duy nhất. Một cấu trúc song song chia luồng hiện tại thành một nhóm luồng mới trong khoảng thời gian của khối / câu lệnh tiếp theo, sau đó nhóm này hợp nhất lại thành một. for phân chia công việc của vòng lặp giữa các chủ đề của nhóm hiện tại.

Nó không tạo luồng, nó chỉ phân chia công việc giữa các luồng của nhóm đang thực thi. song song for là cách viết tắt của hai lệnh cùng một lúc: song song và for. Song song tạo một nhóm mới và chia nhóm đó để xử lý các phần khác nhau của vòng lặp. Nếu chương trình của bạn không bao giờ chứa một cấu trúc song song, không bao giờ có nhiều hơn một luồng; luồng chính khởi động chương trình và chạy nó, như trong các chương trình không phân luồng.

https://bisqwit.iki.fi/story/howto/openmp/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.