Bài 1 - OpenMP Lập Trình Xử Lý Song Song - Giới Thiệu

Chào mọi người, gần đây Mark có nghiên cứu về lập trình xử lý song song openMP, muốn ghi chép lại những gì đã học được, mục đích là để khi nào quên thì lôi ra xem lại, đồng thời chia sẻ với những ai đang tìm hiểu ~

Hy vọng những ai hiện đang nghiên cứu về lĩnh vực này có thể chỉ giáo thêm ! ^^

-------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------
Sơ Lược Về  "multi thread"

Phần lớn lập trình chỉ chạy với một nhân (thread), đến khi chạy hết công suất 100%, mới chuyển tiếp qua dùng nhân tiếp theo, gọi là lập trình single thread, nếu như thế đối với CPU nhiều nhân thì cũng không thể nâng cao hiệu năng của hệ thống ( ý nói về thời gian xử lý). Nhưng đối với lập trình multi thread, thì có thể đồng bộ hóa các nhân, xử lí tính toán cùng một lúc, như vậy thời gian xử lý sẽ nhanh hơn rất nhiều.
  Lấy một ví dụ đơn giản, nếu dùng single thread để giải quyết một sự việc, làm một lần hết 10s, nếu phải làm 10 lần thì 10s*10 = 100s, cần 100s mới có thể hoàn tất công việc; nhưng nếu dùng multi thread đối với CPU 2 nhân, chúng ta có thể chia công việc cho 2 nhân riêng biệt, mỗi nhân xử lý 5 lần, như vậy thời gian hoàn tất công việc chỉ cần khoảng 50s thôi;

 Nhưng trên thực tế, lập trình multi thread không đơn giản như mình nghĩ. Nào là phân chia công việc, phân chia dữ liệu, cũng tốn thêm thời gian, đối với CPU 2 nhân xử lý trong trường hợp lý tưởng nhất thì hiệu ứng hệ thống cũng không thể là 1 + 1 = 2 được. Hơn nữa, không phải loại công việc nào cũng có thể phân chia để đồng bộ hóa được ! rất nhiều loại công việc đều có sự liên kết với nhau, như vậy nếu phân chia cho các nhân để xử lý riêng biệt, kết quả cho ra chắc chắn có vấn đề. Ngoài ra multi thread khi lập trình và sửa chữa đều khó khăn và phức tạp hơn so với single thread.

   Hiện tại CPU máy tính ngày càng phát triển, 2 nhân, 4 nhân ... và cao nhất là 16 nhân, đồng thời có loại một bản mạch cao nhất có thể dùng 4 CPU 16,  4 * 16 = 64 nhân. Dùng nhiều nhân để tính toán, thời gian xử lý chắc chắn sẽ giảm được rất nhiều lần.!
--------------------------------------------------------------------------------------------------------------------------
Lập trình với OpenMP

Nếu bạn đang dùng Visual C++, chỉ cần vào Project -> projecties ->C/C++ ->Language->OpenMP Support mở lên (tham số /openmp), như vậy VC++ khi biên dịch có thể sử dụng ngữ pháp của OpenMP rồi;


Khi lập trình với OpenMP, các bạn nên include OpenMP vào trong header file nhé !
#include <omp.h>

Lập trình OpenMP có thể thông qua những dòng lệnh cấp cao, rất đơn giản để chuyển thành dạng xử lý song song, đạt kết quả tăng tốc cho hệ thống bằng cách dùng multi thread API; Trong trường hợp đơn giản nhất, chỉ cần một dòng lệnh là có thể khống chế các vòng lặp thành xử lý song song !

Nếu muốn chuyển vòng lặp for thành dạng xử lý song song , phải làm thế nào ?
Rất đơn giản , chỉ cần thêm vào trước vòng lặp một dòng lệnh :

     #pragma omp parallel for

như vậy là OK rồi ! Để hiểu rõ hơn, chúng ta cùng xem đoạn lập trình đơn giản này nhé !















    Ở đoạn code trên, trong hàm main() là một vòng lặp đơn giản, chạy 10 lần, mỗi lần đều gọi hàm show() và in ra các giá trị của i .

    Nếu lập trình trên giao diện Ubuntu, chúng ta có thể biên dịch như sau :
Ví dụ file chương trình là test.c
Ta có thể biên dịch :     gcc  test.c   -o  test
Sau đó chạy chương trình :     ./test

Đương nhiên ta sẽ được kết quả :








Nếu muốn dùng OpenMP để chuyển vòng lặp for thành xử lý song song, chúng ta chỉ cần sửa thêm vào như sau :











Đơn giản, từ đầu đến cuối chỉ cần thêm vào 2 dòng (trong khung màu xanh), và chúng ta bắt đầu chạy chương trình. Đối với hệ thống Ubuntu, ta cần phải include thêm thư viện của OpenMP vào nữa, chúng ta biên dịch như sau :
   biên dịch  :    gcc   -fopenmp   test.c   -o   testOMP
   chạy  :      ./testOMP

Chúng ta được kết quả :








Từ kết quả trên, chúng ta có thể thấy, hệ thống không chạy theo thứ tự từ 0 đến 9 nữa ! mà OpenMP đã phân chia vòng lặp từ 0 - 9 thành 2 phần là 0 - 4, và 5 - 9, sau đó giao cho từng thread xử lý, bởi vậy chúng ta mới có kết quả như vậy.


Ở đây chỉ là ví dụ đơn giản, chưa hiện rõ sự khác biệt về tốc độ xử lý, nếu như cần phải tính toán với lượng dữ liệu lớn , và mức tính toán phức tạp hơn thì các bạn có thể thấy rõ hơn về công dụng của OpenMP trong trình xử lý song song. Khi cho chương trình chạy, chúng ta có thể thông qua trình quản lý để xem các nhân đang hoạt động như thế nào. Khi chạy với lập trình OpenMP,  thông thường các nhân đều chạy với công suất 100%...hehe...Nhưng các bạn cứ yên tâm, có lẽ sẽ không bị đứng máy đâu !



--------------------------------------------------------------------------------------------------------------------------


Qua bài viết này, chúng ta mới chỉ học được 2 dòng lệnh , thực tế thì OpenMP còn nhiều lệnh khác, nhưng thực sự dùng đến cũng không nhiều. Bài viết sau, mình sẽ giới thiệu thêm !


Nếu có chỗ nào còn chưa đúng, xin các bạn góp ý chỉ bảo  !










Comments

Popular posts from this blog

CUDA - Texture