Câu trả lời đơn giản:
OpenMP chỉ được sử dụng để khai thác nhiều luồng cho nhiều lõi. Mở rộng simd
mới này cho phép bạn sử dụng rõ ràng các hướng dẫn SIM SIMD trên các CPU hiện đại, chẳng hạn như Intel AVX/SSE và NEON của ARM.
(Lưu ý rằng lệnh SIMD được thực hiện trong một luồng đơn và một lõi đơn, theo thiết kế. Tuy nhiên, ý nghĩa của SIMD có thể được mở rộng cho GPGPU. Nhưng, tôi không nghĩ bạn cần xem xét GPGPU cho OpenMP 4.0.)
Vì vậy, một khi bạn biết hướng dẫn SIMD, bạn có thể sử dụng cấu trúc mới này.
Trong một CPU hiện đại, khoảng có ba loại song song: (1) hướng dẫn cấp xử lý song song (ILP), (2) đề cấp xử lý song song (TLP), và (3) hướng dẫn SIMD (chúng tôi có thể nói đây là cấp độ vectơ hoặc hơn).
ILP được thực hiện tự động bởi các CPU không theo đơn đặt hàng hoặc trình biên dịch. Bạn có thể khai thác TLP bằng cách sử dụng Open2's parallel for
và các thư viện luồng khác. Vậy, SIMD thì sao? Intrinsics là một cách để sử dụng chúng (cũng như vector hóa tự động của trình biên dịch). Open23's simd
là một cách mới để sử dụng SIMD.
Đi một ví dụ rất đơn giản:
for (int i = 0; i < N; ++i)
A[i] = B[i] + C[i];
Đoạn mã trên sẽ tính toán một tổng của hai vectơ N-chiều.Như bạn có thể dễ dàng thấy, không có (loop-carried) data dependency trên mảng A[]
. Vòng lặp này là embarrassingly parallel.
Có thể có nhiều cách để song song vòng lặp này. Ví dụ, cho đến OpenMP 4.0, điều này có thể được song song chỉ sử dụng cấu trúc parallel for
. Mỗi chuỗi sẽ thực hiện N/#thread
lặp trên nhiều lõi.
Tuy nhiên, bạn có thể nghĩ rằng việc sử dụng nhiều chuỗi để bổ sung đơn giản như vậy sẽ là quá mức cần thiết. Đó là lý do tại sao có vectorization, mà chủ yếu được thực hiện bởi các hướng dẫn SIMD.
Sử dụng một SIMD sẽ là như thế này:
for (int i = 0; i < N/8; ++i)
VECTOR_ADD(A + i, B + i, C + i);
Mã này giả định rằng (1) hướng dẫn SIMD (VECTOR_ADD
) là 256-bit hoặc 8-way (8 * 32 bit); và (2) N
là bội số của 8.
Lệnh SIMD 8 chiều có nghĩa là 8 mục trong vectơ có thể được thực hiện trong một lệnh máy. Lưu ý rằng AVX mới nhất của Intel cung cấp hướng dẫn vector 8 chiều (32-bit * 8 = 256 bit).
Trong SIMD, bạn vẫn sử dụng một lõi đơn (một lần nữa, điều này chỉ dành cho các CPU thông thường chứ không phải GPU). Tuy nhiên, bạn có thể sử dụng một song song ẩn trong phần cứng. CPU hiện đại dành tài nguyên phần cứng cho hướng dẫn SIMD, trong đó mỗi SIMD lane có thể được thực thi song song.
Bạn có thể sử dụng song song cấp chủ đề cùng một lúc. Ví dụ trên có thể được song song thêm bởi parallel for
.
(Tuy nhiên, tôi nghi ngờ có bao nhiêu vòng lặp thực sự có thể được chuyển thành vòng SIMDized. Đặc tả OpenMP 4.0 dường như không rõ ràng về điều này. Vì vậy, hiệu suất thực tế và hạn chế thực tế sẽ phụ thuộc vào việc triển khai trình biên dịch thực tế).
để tóm tắt, simd
xây dựng cho phép bạn sử dụng các chỉ lệnh SIMD, đến lượt nó, song song hơn có thể được khai thác cùng với thread-mức xử lý song song. Tuy nhiên, tôi nghĩ rằng việc triển khai thực sự sẽ quan trọng.
openmp là SIMD up uintil phiên bản 3.0, sau đó họ đã loại bỏ khái niệm đó. Tôi đoán pragma mới là khả năng tương thích ngược với mã cũ dựa trên một số khía cạnh của SIMD. không nên các tài liệu openmp có gì để nói về điều đó? –
Nó không phải là 'song song simd'; bạn sử dụng 'song'' _or_' simd', gợi ý về sự khác biệt. Xem bên dưới. –
@JD: Đó là một lỗi đánh máy, tất nhiên. Đã sửa lỗi, nhờ –