Trong vòng bốn thập kỷ qua, chúng ta đã chứng kiến sự phát triển như vũ bão của máy tính. Đúng như những gì định luật Moore đã phát biểu, tốc độ của vi xử lý tăng theo lũy thừa của 2 theo mỗi 5 năm. Điều này tạo bước đệm cho sự ra đời của hàng loạt các phát minh công nghệ, trong đó có trí tuệ nhân tạo, internet vạn vật và nhiều phát minh khác nữa. Nhưng có vẻ như quá trình đó sắp phải dừng lại khi chúng ta đã dần chạm tới giới hạn của vật lý, số lượng bóng bán dẫn trên một đơn vị diện tích đã đạt tới cực hạn. Một câu hỏi đặt ra, liệu chúng ta còn có thể cải thiện hiệu năng tính toán được hơn nữa hay không? Câu trả lời là có nhưng thay vì cải thiện tốc độ phần cứng chúng ta sẽ cải thiện cách thức tính toán. Một trong những phương pháp lâu đời nhất để đạt được điều này đó chính là tính toán song song. Minh họa một cách đơn giản, tính toán tuần tự truyền thống giống như một người đọc một đoạn văn bản từ đầu đến cuối trong khi ở tính toán song song, đoạn văn bản đó được chia thành nhiều phần và có nhiều người đảm nhiệm việc đọc cho từng phần. Có thể dễ dàng nhận thấy khi một công việc được chia nhỏ và thực hiện đồng thời một cách riêng rẽ, hiệu suất thời gian cũng được cải thiện đáng kể. Đây chính là ưu điểm then chốt của tính toán song song so với các loại hình tính toán truyền thống khác. Trong đề tài này chúng tôi sẽ minh họa sức mạnh then chốt ấy qua việc giải quyết bài toán nhân ma trận trên cả hai mô hình và so sánh hiệu suất. Dù đã cố gắng hết sức để tránh khỏi những sai sót trong quá trình thực hiện đề tài nhưng tôi biết vẫn còn đâu đó những vụn lỗi nhỏ và mong được châm trước cho điều này. Tôi cũng chân thành gửi lời cảm ơn đến TS. Hà Mạnh Đào, người đã hỗ trợ chúng tôi trong quá trình thực hiện đề tài này.
TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP HÀ NỘI KHOA CÔNG NGHỆ THƠNG TIN ======***====== BÁO CÁO BTL THUỘC HỌC PHẦN: TÍNH TOÁN HIỆU NĂNG CAO Đề tài: Đánh giá hiệu toán nhân ma trận GVHD: Ts Hà Mạnh Đào Nhóm - Lớp: – 2023IT6069001 Thành viên: Bùi Trường Giang - 2021601506 Phan Văn Thức - 2021603496 Phạm Đức Duy - 2021602655 Hà nội, Năm 2023 Giới thiệu chung Trong vòng bốn thập kỷ qua, chứng kiến phát triển vũ bão máy tính Đúng định luật Moore phát biểu, tốc độ vi xử lý tăng theo lũy thừa theo năm Điều tạo bước đệm cho đời hàng loạt phát minh cơng nghệ, có trí tuệ nhân tạo, internet vạn vật nhiều phát minh khác Nhưng q trình phải dừng lại dần chạm tới giới hạn vật lý, số lượng bóng bán dẫn đơn vị diện tích đạt tới cực hạn Một câu hỏi đặt ra, liệu cịn cải thiện hiệu tính tốn hay khơng? Câu trả lời có thay cải thiện tốc độ phần cứng cải thiện cách thức tính tốn Một phương pháp lâu đời để đạt điều tính tốn song song Minh họa cách đơn giản, tính toán truyền thống giống người đọc đoạn văn từ đầu đến cuối tính tốn song song, đoạn văn chia thành nhiều phần có nhiều người đảm nhiệm việc đọc cho phần Có thể dễ dàng nhận thấy công việc chia nhỏ thực đồng thời cách riêng rẽ, hiệu suất thời gian cải thiện đáng kể Đây ưu điểm then chốt tính tốn song song so với loại hình tính tốn truyền thống khác Trong đề tài minh họa sức mạnh then chốt qua việc giải toán nhân ma trận hai mơ hình so sánh hiệu suất Dù cố gắng để tránh khỏi sai sót q trình thực đề tài tơi biết cịn vụn lỗi nhỏ mong châm trước cho điều Tôi chân thành gửi lời cảm ơn đến TS Hà Mạnh Đào, người hỗ trợ trình thực đề tài Mục lục Giới thiệu chung .2 Phần I: Mở đầu 1.1 Giới thiệu OpenMP thư viện 1.1.1 OpenMP gì? 1.1.2 Mơ hình song song OpenMP .4 1.1.3 Tổng quan API OpenMP 1.1.4 Cú pháp OpenMP Phần 2: Kết nghiên cứu 13 2.1 Bài toán nhân ma trận 13 2.1.1 Tổng quan toán 13 2.1.2 Thuật toán Fox .14 Phần 3: Kết luận học kinh nghiệm 22 3.1 Kết đánh giá ma trận khác 22 3.1.1 Thông số hệ thống 22 3.1.2 Thiết lập toán 22 3.1.3 Thống kê thời gian .22 3.1.4 Nhận xét 23 3.2 Các kiến thức kĩ học .23 TÀI LIỆU THAM KHẢO .24 Danh mục hình ảnh Hình 1 Mơ hình lập trình nhớ chia sẻ Hình Minh họa mơ hình Fork join OpenMP Hình Ví dụ ma trận tổng qt Hình 2 Minh họa phép nhân ma trận Hình Minh họa cách chia ma trận thành khối ma trận 6 13 14 15 Hình Minh họa q trình dịch vịng khối ma trận theo thuật tốn Fox Hình Hàm cài đặt Fox hồn chỉnh Hình Đoạn mã lấy id luồng hành Hình Đoạn mã xác định khối cần tính tương ứng với luồng hành Hình Ba trỏ tương ứng ô nhớ ma trận Hình Lặp n lần với biến gặp state Hình 10 Tính giá trị trỏ A1, B1, B1 state Hình 11 Thực nhân khối cộng vào ma trận C 15 16 16 16 16 16 17 17 Phần I: Mở đầu 1.1 Giới thiệu OpenMP thư viện 1.1.1 OpenMP gì? – OpenMP giao diện lập trình ứng dụng(API) định nghĩa nhóm tổ chức phần cứng chuyên dụng nhà cung cấp phần mềm OpenMP cung cấp mô hình lập trình linh động, mở rộng cho nhà phát triển mơ hình tính tốn song song cho nhớ chia sẻ – OpenMP hỗ trợ ngôn ngữ C/C++ Fortran lượng rộng kiến trúc phần cứng khác Trong đề tài sử dụng OpenMP môi trường C++ để cài đặt minh họa hiệu suất thuật toán nhân ma trận làm việc hai mơ hình lập trình song song 1.1.2 Mơ hình song song OpenMP – Cơ chế đa luồng ● OpenMP thực việc tính tốn song song tuân theo chế đa luồng Luồng đơn vị thực thi nhỏ tiến trình lịch hệ điều hành Trong tiến trình có nhiều luồng thực thi – Song song tường minh ● Không giống số mơ hình lập trình song song trừu tượng hóa tự động khác, OpenMP yêu cầu người lập trình điều khiển tồn hoạt động tính tốn song song Một chương trình song song xây dựng OpenMP việc chèn thêm thị tiền xử lý vào chương trình bình thường – Cơ chế nhớ chia sẻ Hình 1 Mơ hình lập trình nhớ chia sẻ ● OpenMP thiết kế cho hệ thống đa nhân chia sẻ nhớ kiến trúc kể tên UMA, hay NUMA Trong OpenMP luồng truy cập đến vùng nhớ tồn cục Dữ liệu tồn cục riêng tư luồng Việc đồng hóa thực người lập trình phần lớn tự động – Mơ hình fork – join ● OpenMP sử dụng mơ hình fork-join cho việc thực thi song song Một chương trình OpenMP ban đầu tiến trình đơn thực gặp đoạn thị song song rẽ nhánh thành chương trình con, sau thực xong lại luồng Fork q trình rẽ nhánh, Join trình hợp lại Hình Minh họa mơ hình Fork join OpenMP – Các đoạn song song lồng ● OpenMP luồng song song tiếp tục tách thành luồng song song nhỏ nhằm đẩy mạnh tốc độ tính tốn 1.1.3 Tổng quan API OpenMP – OpenMP gồm thành phần sau: ● Các thị biên dịch ● Thư viện lập lịch thời gian chạy ● Các biến môi trường –Cấu trúc thị biên dịch OpenMP ● Chỉ thị biên dịch sử dụng với mục đích: ▪ Sinh luồng chương trình song song ▪ Phân chia khối lệnh luồng ▪ Thực đoạn mã định ▪ Đồng hóa cơng việc luồng ●Cú pháp thị tiền xử lý OpenMP C++ #pragma omp [Tên thị] [Các đối số bổ sung] –Thư viện lập lịch thời gian chạy ● OpenMP bao gồm nhiều thư viện lập lịch thời gian chạy với sử dụng cho mục đích sau: ▪ Thiết đặt truy vấn số luồng ▪ Truy vấn id luồng, số luồng có ▪ Truy vấn chu kỳ đồng hồ phân giải –Các biến môi trường ● OpenMP cung cấp biến môi trường giúp người lập trình cấu hình thời gian chạy cho đoạn thực thi song song ● Biến môi trường thường sử dụng cho mục đích sau ▪ Thiết đặt số luồng ▪ Chỉ định cách lần lặp vòng lặp chia cho luồng ▪ Gán luồng với tiến trình ▪ Thiết lập cấu trúc ngăn xếp –Cấu trúc tổng quát đoạn chương trình OpenMP #include main () { int var1, var2, var3; Đoạn mã Bắt đầu đoạn mã song song thị biên dịch #pragma omp parallel private(var1, var2) shared(var3) { Parallel section executed by all threads Other OpenMP directives Run-time Library calls All threads join master thread and disband } Đoạn mã } 1.1.4 Cú pháp OpenMP – Một số thị tiền xử lý ● parallel: Chỉ thị bắt đầu đoạn code song song ● for: Thực vòng lặp for bên vùng song song chia cho luồng ● sections: Xác định phần mã chia sẻ cho luồng ● single: Chỉ định phần mã thực thi luồng ● master: Chỉ luồng thực thi chương trình ● critical: Chỉ định phần mã đoạn giới hạn (Đoạn chương trình sử dụng tài nguyên gang) ● barrier: Tạo chặn ngăn luồng tiếp tục thực thi tất luồng khác xong ● atomic: Chỉ phần nhớ cập nhật luồng thời điểm ● flush: Chỉ định luồng có khung nhìn chung cho nhớ chia sẻ ● ordered: Chỉ định thứ tự thực vòng lặp for song song ● threadprivate: Chỉ định biến riêng luồng – Các hàm quan trọng ● omp_get_thread_num(): Lấy số lượng luồng thời ● omp_get_num_thread(): Lấy id luồng ● num_threads(): Chỉ định số luồng thực Phần 2: Kết nghiên cứu 2.1 Bài toán nhân ma trận 2.1.1 Tổng quan toán – Khái niệm ma trận nhân ma trận Ma trận mảng chữ nhật gồm số, ký hiệu, biểu thức, xếp theo hàng cột mà ma trận tuân theo quy tắc định trước Các ô ma trận gọi phần tử ma trận Các phần tử xác định hai số hàng cột tài liệu dùng hai biến tương ứng i, j Phần tử hang thứ i cột j kí hiệu aij Ma trận thường viết dấu ngoặc vng: Hình Ví dụ ma trận tổng quát Trong nhiều toán, ma trận biểu diễn liệu phép biến đổi tốn Như xử lý ảnh ta có ma trận điểm ảnh, học máy ta có ma trận vector đặc trưng… Để giải toán thao tác tính tốn phố biến thực phép nhân ma trận Phép nhân ma trận thực số lượng cột ma trận thứ phải số lượng hàng ma trận thứ hai Ma trận kết qua gọi tích ma trận, có kích cỡ số hàng ma trận số cột ma trận thứ hai Nếu ma trận A có kích thước (n x k) ma trận B có kích thước (k x m) ma trận kết C có kích thước (m x n) Phần tử Cij xác định cơng thức: Hình 2 Minh họa phép nhân ma trận – Độ phức tạp thuật toán ● Ma trận kết có kích thước n x m ● Để tính tốn ma trận kết quả, ta cần k phép nhân độ phức tạp thuật toán n x m x k ● Đây độ phức tạp tương đối lớn thực tính tốn Đối với tốn trí tuệ nhân tạo, ma trận vector đặc trưng lên đến hàng nghìn kéo theo phép toán cần thực lên đến hàng tỷ Một số không nhỏ thực máy tính Thời gian tính tốn lên đến hàng hàng ngày ● Điều giải việc phân cơng việc tính tốn cho tiến trình thực song song Trên thực tế có nhiều phương pháp để thực điều này, đề tài để minh họa q trình chúng tơi xin sử dụng thuật toán Fox 2.1.2 Thuật toán Fox – Tổng quan thuật tốn Fox Fox thuật tóa nhân ma trận song song thực việc chia ma trận vuông thành ma trận bàn cờ, tiến trình đảm nhiệm việc tính tốn ma trận ma trận kết Việc phân chia công việc tính tốn thực đồng thời luồng giúp tăng hiệu suất nhân ma trận lên mức vượt trội – Các bước thuật toán Fox thực – Gọi hai ma trận cần nhân A B – Ma trận A B chia thành khối ma trận Hình Minh họa cách chia ma trận thành khối ma trận – Ta coi ma trận A, B ma trận khối ma trận Một ma trận xác định thông qua hai số hàng cột tương ứng với i j – Ở thời điểm ban đầu ma trận A hàng khối thứ i dịch vòng qua phải sang i đơn vị, ma trận B cột khối thứ j dịch vòng lên j đơn vị thứ i, j tính từ Khởi tạo ma trận C ma trận – Thuật toán trải qua n bước lặp bước lặp thứ k, ma trận khối C ij cộng thêm lượng Aij * Bij Sau bước lặp dịch hàng ma trận A thêm sang phải, dịch cột ma trận B thêm lên Hình Minh họa trình dịch vịng khối ma trận theo thuật toán Fox – Sau n bước lặp ta thu ma trận C ma trận kết – Thuật toán Fox thực song song – Các bước số 2, thay thực luồng khối ma trận chia cho luồng đảm nhận Mỗi luồng chịu trách nhiệm cho việc tính tốn khối ma trận ma trận kết – Trong mô hình này, việc dịch dịng cột khơng thực tiếp mà dịch logic Hình Hàm cài đặt Fox hoàn chỉnh – Hàm nhân ma trận nhận vào A, B, C A B hai ma trận cần nhân, C ma trận kết – Giải thích đoạn mã Hình Đoạn mã lấy id luồng hành Hình Đoạn mã xác định khối cần tính tương ứng với luồng hành Hình Ba trỏ tương ứng ô nhớ ma trận Hình Lặp n lần với biến gặp state Hình 10 Tính giá trị trỏ A1, B1, B1 state Hình 11 Thực nhân khối cộng vào ma trận C – Một số lưu ý: – Số luồng thực cần phải số phương ước số phần tử ma trận, khơng thuật tốn khơng hoạt động xác – Chương trình hồn thiện kèm driver code cho việc đánh giá hiệu #include #include #include #include #include void matrix_creation(double** pA, double** pB, double** pC, int size) { *pA = (double*)malloc(size * size * sizeof(double)); (double*)malloc(size * size * sizeof(double)); *pC = (double*)calloc(size * size, sizeof(double)); } void matrix_initialization(double* A, double* B, int size, int sup) { srand(time(NULL)); *pB = for (int i = 0; i < size * size; ++i) { *(A + i) = rand() % sup + 1; *(B + i) = rand() % sup + 1; } } void matrix_dot(double* A, double* B, double* C, int n) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { for (int k = 0; k < n; ++k) { *(C + i * n + j) += *(A + i * n + k) * *(B + k * n + j); } } } } int matrix_check(double* A, double* B, int n) { for (int i = 0; i < n * n; ++i) { if (*(A + i) != *(B + i)) { return 0; } } return 1; } void matrix_print(double* A, int n) { printf(" -~ -~ -~ -~ -\n"); for (int i = 0; i < n * n; ++i) { printf("%.2lf ", *(A + i)); if ((i + 1) % n == 0) { printf("\n"); } } printf(" -~ -~ -~ -~ -\n"); } void matrix_removal(double** pA, double** pB, double** pC) { free(*pA); free(*pB); free(*pC); } /* FoxAlgorithm */ void FoxAlgorithm(double* A, double* B, double* C, int m_size, int* save, int trd) { int stage; #pragma omp parallel private(stage) shared(A, B, C) num_threads(trd) { int n_threads = omp_get_num_threads(); *save = n_threads; int n_blocks = sqrt(n_threads); int block_size = m_size / n_blocks; int PrNum = omp_get_thread_num(); int i1 = PrNum / n_blocks, j1 = PrNum % n_blocks; double* A1, * B1, * C1; for (stage = 0; stage < n_blocks; ++stage) { A1 = A + (i1 * m_size + ((i1 + stage) % n_blocks)) * block_size; B1 = B + (((i1 + stage) % n_blocks) * m_size + j1) * block_size; C1 = C + (i1 * m_size + j1) * block_size; for (int i = 0; i < block_size; ++i) { for (int j = 0; j < block_size; ++j) { for (int k = 0; k < block_size; ++k) { *(C1 + i * m_size + j) += *(A1 + i * m_size + k) * *(B1 + k * m_size + j); } } } } } } void SerializeAlgorithm(double* A, double* B, double* C, int m_size) { double* A1 = A; double* B1 = B; double* C1 = C; for (int i = 0; i < m_size; ++i) { for (int j = 0; j < m_size; ++j) { for (int k = 0; k < m_size; ++k) { *(C1 + i * m_size + j) += *(A1 + i * m_size + k) * *(B1 + k* m_size + j); } } }} /* */ int main(int argc, char** argv) { int n_threads = 16; int m_size = n_threads * 100; if (argc == 2) { sscanf_s(argv[1], "%d", &m_size); } double* pA, * pB, * pC; matrix_creation(&pA, &pB, &pC, m_size); matrix_initialization(pA, pB, m_size, 1000); double start_time = omp_get_wtime(); FoxAlgorithm(pA, pB, pC, m_size, &n_threads, n_threads); /*printf("\n"); matrix_print(pC, n_threads);*/ double end_time_fox = omp_get_wtime() - start_time; printf("%.5lf, %d, %d\n", end_time_fox, n_threads, m_size); start_time = omp_get_wtime(); SerializeAlgorithm(pA, pB, pC, m_size); double end_time_serialize = omp_get_wtime() - start_time; printf("%.5lf, %d, %d\n", end_time_serialize, n_threads, m_size); matrix_removal(&pA, &pB, &pC); return 0;} Phần 3: Kết luận học kinh nghiệm 3.1 Kết đánh giá ma trận khác 3.1.1 Thơng số hệ thống – Chương trình thực thi môi trường Microsoft Studio, với thiết bị chạy CPU Bộ xử lý Intel® Core™ i5-12500H nhớ đệm 18M, xung tối đa 4,50 GHz, 12 lõi 16 luồng 3.1.2 Thiết lập toán – Để tận dụng tối đa hiệu suất CPU, chương trình thiết lập số luồng 16, kích thước ma trận bội số số luồng (Đảm bảo khối lượng công việc luồng khác nhau) 3.1.3 Thống kê thời gian – Coi phần mã dịng thiết lập q trình trình nhân ma trận, ta lấy 100 đơn vị dịng Ở ta có 13 dịng – Coi phần mã song song phần nhân ma trận, ta lấy n * n * 100 đơn vị với n kích thước ma trận – Hệ số tăng tốc Amdahl’s tính theo cơng thức: Speedup = / (S + P / N) S: Tỉ lệ mã bắt buộc phải P: Tỉ lệ mã song song song hóa N: Số luồng – Sau chạy thử lần với kích thước ma trận khác ta bảng thống kê: – Sau chạy thử lần với kích thước ma trận khác ta bảng thống kê Lần Kích kiểm thước tra ma trận Thời gian nhân song song (s) Thời gian nhân (s) Lượng Lượng mã mã tuần song song tự Hệ số tăng tốc theo Amdahl's Hệ số tăng tốc thực tế 0.00614 0.00001 1300 1600 2.0714285 0.00162 64 0.01217 0.00092 1300 4096 3.4678663 0.07559 128 0.02174 0.0218 1300 16384 7.6092943 1.00275 160 0.01681 0.02128 1300 25600 9.2758620 1.26591 1600 1.69029 19.61307 1300 2560000 15.879107 11.6033 3200 16.61166 260.3794 1300 1024000 15.969593 15.6744 3.1.4 Nhận xétn xét –Ở lần thử nghiệm 1, 2, 3, kích thước ma trận khơng đáng kể thước ma trận khơng đáng kể ước lượng đoạn mã song song mang tính xấp xỉ nên dẫn đến lệch nhiều hệ số tăng tốc thực tế hệ số tăng tốc theo Amdahl’s –Sang đến lần thử nghiệm kích thước ma trận hàng nghìn số ước tính bắt đầu gần hệ số tăng tốc thực tế ước tính tiến gần tới số luồng –Điều cho thấy chênh lệch hiệu suất lớn tính tốn song song tính tốn tốn có khối lượng tính tốn khổng lồ Khi lần thử nghiệm với kích thước ma trận 3200 x 3200 Tính tốn song song cho kết với 16 giây tính tốn tận gần phút output tương đương 3.2 Các kiến thức kĩ học –Qua đề tài phần thấy sức mạnh vượt trội tính tốn song song toán lớn Đây tiền để động lực to lớn để nhóm tiếp tục nghiên cứu toán khác tảng tính tốn song song sau