2015-05-16 36 views
7

Khi tôi sử dụng chỉ thị cancel (kể từ OpenMP 4.0) để ngắt vòng lặp song song trong cấu trúc parallel for, GCC 5.1 cảnh báo" '#pragma omp cancel for' inside 'nowait' để xây dựng " cho đoạn mã sau.GCC 5.1 cảnh báo hủy cấu trúc bên trong `song song cho` xây dựng

const int N = 10000; 

int main() 
{ 
    #pragma omp parallel for 
    for (int i = 0; i < N; i++) { 
    #pragma omp cancel for // <-- here 
    } 
} 

http://coliru.stacked-crooked.com/a/de5c52da5a16c154

Đối với cách giải quyết, khi tôi chia để parallel + for cấu trúc, GCC chấp nhận mã âm thầm.

int main() 
{ 
    #pragma omp parallel 
    #pragma omp for 
    for (int i = 0; i < N; i++) { 
    #pragma omp cancel for 
    } 
} 

Nhưng tôi không biết tại sao GCC cảnh báo trường hợp cũ, tuy nhiên cấu trúc không có mệnh đề 'nowait'. OpenMP 4.0 API spec cũng cho biết rằng parallel for bằng các cấu trúc parallel + for.

2.10.1 Parallel Loop Construct

Description

The semantics are identical to explicitly specifying a parallel directive immediately followed by a for directive.

Hành vi của GCC có đúng không? hoặc có điều gì đó sai?

+4

Tôi nghĩ GCC sẽ phát ra một thông báo lỗi tốt hơn. Trình biên dịch Intel ném: "lỗi: hủy bỏ cho phải được lồng nhau chặt chẽ trong một khu vực" cho trường hợp này (mà làm cho một chút ý nghĩa hơn). Mặc dù 'parallel for' và' parallel' theo sau là 'for' tương tự nhau, cấu trúc' cancel' chỉ cho phép một mệnh đề ... methinks trình biên dịch đọc mệnh đề theo sau là 'cancel' và kiểm tra cấu trúc kèm theo là gì, trong ví dụ đầu tiên của bạn, nó là một 'song song cho' và không phải là' for', do đó trình biên dịch ném lỗi đó. Chỉ cần 2 xu của tôi. – Sayan

+0

GCC đưa ra cảnh báo, Clang không đưa ra cảnh báo và ICC không thể biên dịch trong trường hợp đầu tiên. Tất cả ba trình biên dịch biên dịch mà không cần cảnh báo trong trường hợp thứ hai. Hấp dẫn. –

+0

@Sayan, tôi không chắc tại sao thông báo lỗi của ICC lại tốt hơn cảnh báo của GCC. Intel dường như nghĩ rằng việc hủy bỏ không phải là bên trong một vòng lặp mà nó rõ ràng là. Nó có vẻ như trường hợp này https://software.intel.com/en-us/articles/cdiag1159 mà trình biên dịch cung cấp cho các lỗi chính xác cho. –

Trả lời

0

tôi đoán là mã của bạn

#pragma omp parallel for 
    for (int i = 0; i < N; i++) { 
    #pragma omp cancel for 
    } 

không tương đương với

#pragma omp parallel 
    { 
    #pragma omp for 
    for (int i = 0; i < N; i++) { 
    #pragma omp cancel for 
    } 
    } //end of parallel region 

trong trường hợp thứ hai, sẽ có hai rào cản: một ở phần cuối của cho và một ở cuối của khu vực song song; một cái gì đó tương đương với:

#pragma omp parallel 
    { 
     #pragma omp for nowait 
     for (int i = 0; i < N; i++) { 
      #pragma omp cancel for 
     } 
     #pragma omp barrier 
    } // and here another implicit barrier 

nhưng tôi đoán rằng mục đích tối ưu hóa, các compilter có thể cố gắng để loại bỏ các rào cản hưởng ứng nhiệt liệt thứ hai và tạo ra:

#pragma omp parallel 
    { 
     #pragma omp for nowait 
     for (int i = 0; i < N; i++) { 
      #pragma omp cancel for 
     } 
    } 

mà là nhiều 'tối ưu' nhưng có nhược điểm để cảnh báo về việc phải chờ đợi và hủy bỏ hỗn hợp.

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