2008-11-01 88 views
8

Gần đây tôi đã viết rất nhiều về tính toán và lập trình song song và tôi nhận thấy rằng có rất nhiều mẫu xuất hiện khi nói đến tính toán song song. Lưu ý rằng Microsoft đã phát hành một thư viện cùng với Microsoft Visual C++ 2010 Community Technical Preview (có tên là Parallel Patterns Library) Tôi đang tự hỏi các mẫu lập trình song song chung mà bạn đang sử dụng và gặp phải là gì đáng nhớ? Bạn có bất kỳ thành ngữ bạn làm theo và các mẫu mà bạn dường như giữ popping lên khi bạn viết chương trình song song với C + +?Lập trình song song và C++

+0

Bạn có thể làm rõ những gì loại lập trình song song bạn quan tâm? Lập trình phân tán bằng cách sử dụng MPI khác biệt đáng kể so với tính song song mức vòng lặp sử dụng OpenMP. – mch

+0

Tôi đặc biệt quan tâm đến các mẫu chung và thành ngữ trong lập trình song song - cho dù đó là với các mô hình bộ nhớ phân tán hoặc bộ nhớ chia sẻ trên một máy đơn lẻ hoặc nhiều máy. –

Trả lời

17

Patterns:

  • Sản xuất/tiêu dùng

    • Một Chủ đề tạo ra dữ liệu
    • Một đề tiêu thụ dữ liệu
  • Vòng song song

    • Nếu bạn có thể chứng minh rằng mỗi vòng lặp là độc lập
      mỗi lần lặp có thể được thực hiện trong một thread sperate
  • Re-Draw Chủ đề

    • đề khác làm việc và cập nhật dữ liệu cấu trúc nhưng một màn hình vẽ lại chỉ.
  • Main-Event Chủ đề

    • Nhiều chủ đề có thể được tạo ra các sự kiện
    • Một thread có để xử lý các sự kiện (như trật tự là rất quan trọng)
    • có nên cố gắng tách các tổ chức sự kiện Chủ đề/Re -Draw Thread
      Điều này (giúp) ngăn giao diện người dùng bị đóng băng
      Nhưng có thể gây ra quá nhiều lần rút lại nếu không được thực hiện cẩn thận.
  • Work Group

    • Một tập hợp các đề chờ việc làm trên một que.
    • Chủ đề trích xuất một mục công việc khỏi hàng đợi (chờ đợi nếu không có mục nào).
      Chủ đề hoạt động trên một mục công việc cho đến khi hoàn thành
      Khi chuỗi hoàn thành trở về hàng đợi.
+0

Danh sách tuyệt vời, cảm ơn! –

+0

Nếu chủ đề vẽ lại cần sử dụng cấu trúc dữ liệu khi vẽ thì sao?Tôi có nghĩa là, nó không nguy hiểm mà nó đọc từ họ trong khi các chủ đề khác đang cập nhật chúng? – leod

+0

Trừ khi chủ đề vẽ lại được liên kết với một đối tượng đang hoạt động, nơi các thay đổi được "tuần tự hóa" và đối tượng hoạt động "sở hữu" các cấu trúc dữ liệu đã được sửa đổi. –

2

Trước tiên, bạn phải chọn giữa tính toán bộ nhớ chia sẻ và tính toán không chia sẻ. Chia sẻ bộ nhớ là dễ dàng hơn, nhưng không quy mô mà tốt - bạn sẽ sử dụng chia sẻ-không có gì nếu bạn có

a) có một cụm, chứ không phải là một hệ thống đa xử lý, hoặc

b) nếu bạn có nhiều CPU (giả sử,> 60) và mức độ bộ nhớ không đồng bộ cao

Đối với bộ nhớ dùng chung, giải pháp chung là sử dụng các chủ đề; chúng dễ hiểu như một khái niệm và dễ sử dụng trong API (nhưng khó gỡ lỗi).

Để chia sẻ không có gì, bạn sử dụng một số loại tin nhắn. Trong tính toán hiệu suất cao, MPI được thiết lập như là phần mềm trung gian nhắn tin.

Bạn cũng cần phải thiết kế kiến ​​trúc cho các hoạt động song song. Cách tiếp cận phổ biến nhất (một lần nữa bởi vì nó dễ hiểu) là mô hình nông dân-công nhân (a.k.a. master-slave).

+0

Để công bằng, bạn không nhất thiết phải chọn một - bạn có thể tạo kiến ​​trúc hỗ trợ cả hai. Nhưng những điểm này là hợp lệ - bạn cần phải rõ ràng về việc bạn đang hỗ trợ ở đâu bởi vì các yêu cầu (và thường là các thiết kế) là hoàn toàn khác nhau. –

2

Patterns Thực hiện song song

lập trình song song có cấu trúc với các mẫu xác định là một phương pháp cao cấp chủ yếu dựa trên một tập hợp các mô hình thực hiện song song tái phát, thường được gọi bộ xương như thuật toán hay cấu trúc song song , mô tả chương trình trừu tượng và ẩn các chi tiết đa luồng mức thấp và nhiều phức tạp vốn có trong tính song song từ các lập trình viên.

Các mẫu có thể sử dụng lại này tự động hóa nhiều quy trình liên quan đến mô hình song song như đồng bộ hóa, giao tiếp, phân vùng dữ liệu hoặc lập lịch tác vụ và xử lý chúng trong nội bộ. Cách tiếp cận cấp cao này cố gắng mô hình khóa luồng cấp thấp truyền thống với trừu tượng hơn và một cách dễ dàng hơn để thể hiện tính song song và tập trung năng suất và khả năng lập trình thay vì hiệu suất.

Có nhiều mô hình thường được sử dụng như: Bản đồ-Giảm thiểu, Fork-Join, đường ống hoặc Loop Parallel ...

giấy tờ

"có cấu trúc lập trình song song với mẫu xác định" là một bài báo mà thảo luận về các mẫu này. Bạn cũng có thể xem "MHPM: Mô hình lập trình đa quy mô hỗn hợp: Phương pháp song song linh hoạt" mô tả cách thực hiện C++ của phương pháp này có tên là XPU.

Thư viện

XPU là một nhiệm vụ dựa trên C++ thư viện bao gồm từ một tập hợp các mô hình thực hiện tái sử dụng. Nó cho phép biểu hiện một số dạng song song ở một số mức độ chi tiết bên trong một mô hình lập trình đồng nhất đơn nhất. Thật dễ dàng để sử dụng và minh họa sự can thiệp trong việc sử dụng các mẫu để thiết kế các chương trình song song.

Ví dụ nó cho phép biểu hiện của:

  1. công tác Parallelism Pattern:

    đơn giản hoặc phân cấp Fork/Tham mẫu thực hiện với một số tính năng như phát hiện và bảo vệ dữ liệu được chia sẻ như tự động.

  2. dữ liệu song song Pattern:

    Parallel mẫu vòng lặp với phân vùng dữ liệu mở rộng.

  3. Tính song song tạm thời Mẫu:

    Mẫu thực hiện đường ống.

+0

Bạn có thể bao gồm một mẫu mã nào đó mà bạn đã viết bằng thư viện XPU không? –

0

Bạn có kiến ​​thức cơ bản về tính song song với các phần của chương trình. C++ 17 đang nhận được nhiều người trong số họ (ví dụ: phiên bản song song của việc tìm kiếm, sắp xếp, tìm và bạn bè, map_reduce, bản đồ, giảm, tiền tố_sum ...) xem C++ Extensions for Parallelism

Sau đó, bạn có các mục như tiếp tục. Hãy suy nghĩ std::future nhưng vẫn tiếp tục. Có rất ít cách để thực hiện những điều này (boost có một cách tốt nhất hiện nay như là tiêu chuẩn không có phương thức tiếp theo (...) hoặc sau đó (...), nhưng lợi ích lớn là người ta không phải chờ đợi nó để làm các công việc tiếp theo

auto fut = async([](){..some work...}).then([](result_of_prev){...more work}).then... ; 
fut.wait(); 

sự thiếu đồng bộ giữa các nhiệm vụ tiếp theo là quan trọng như thông tin liên lạc giữa các tác vụ/chủ đề/... là những gì làm chậm chương trình xuống song song.

vì vậy, với nhiệm vụ dựa song song thực sự thoải mái. với một lịch trình công việc bạn chỉ cần vượt qua nhiệm vụ tắt và bỏ đi. Họ có thể có phương pháp, giống như một semaphore, để giao tiếp trở lại nhưng đó không phải là bắt buộc. Cả hai Intel Thread Building BlocksMicrosoft Parallel Pattern Library có fa khả năng này.

Sau đó chúng ta có ngã ba/join mẫu. Nó không hàm ý tạo N luồng cho mỗi tác vụ. Chỉ cần bạn có những N, lý tưởng độc lập, điều cần làm (ngã ba) và khi chúng được thực hiện có một điểm đồng bộ hóa ở đâu đó (tham gia).

auto semaphore = make_semaphore(num_tasks); 
add_task([&semaphore]() {...task1...; semaphore.notify(); }); 
add_task([&semaphore]() {...task2...; semaphore.notify(); }); 
... 
add_task([&semaphore]() {...taskN...; semaphore.notify(); }); 
semaphore.wait(); 

Từ trên bạn có thể bắt đầu thấy mẫu này là biểu đồ luồng. Tương lai là (A >> B >> C >> D) và Fork Tham gia là (A | B | C | D). Với điều đó bạn có thể kết hợp chúng để tạo thành một biểu đồ. (A1 >> A2 | B1 >> B2 >> B3 | C1 | D1 >> D2 >> (E1 >> E2 | F1)) Trong đó A1 >> A2 có nghĩa là A1 phải đứng trước A2 và A | B có nghĩa là A và B có thể chạy đồng thời. Các phần chậm ở cuối đồ thị/đồ thị con nơi mọi thứ gặp nhau.

Mục đích là để tìm phần độc lập của hệ thống mà không cần phải giao tiếp. Các thuật toán song song, như đã nói ở trên, hầu như tất cả các trường hợp chậm hơn so với các đối tác tuần tự của chúng cho đến khi tải công việc đủ cao hoặc kích thước đủ lớn (giả sử giao tiếp không quá trò chuyện). Ví dụ phân loại. Trên một máy tính 4 lõi, bạn sẽ nhận được khoảng 2.5X hiệu suất cung cấp hoặc mất vì hợp nhất là chatty và đòi hỏi rất nhiều đồng bộ hóa và không làm việc tất cả các lõi sau vòng đầu tiên hợp nhất. Trên một GPU có N là rất lớn, người ta có thể sử dụng một loại ít hiệu quả hơn, như Bitonic, và nó kết thúc rất nhanh bởi vì bạn có rất nhiều công nhân làm việc thông qua công việc và mọi người đều im lặng làm việc riêng của họ.

Một số thủ thuật để giảm commmunication bao gồm, sử dụng một mảng cho kết quả sao cho mỗi công việc không cố gắng để khóa một đối tượng nhằm thúc đẩy một giá trị. Thường thì việc giảm các kết quả này có thể rất nhanh.

Nhưng với tất cả các loại xử lý song song chậm đi xuất phát từ truyền thông. Giảm nó.