Tải bản đầy đủ (.docx) (23 trang)

Đánh giá hiệu năng bài toán nhân ma trận

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (466.33 KB, 23 trang )

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 TỐN HIỆU NĂNG CAO

Đề tài: Đánh giá hiệu năng bài toán nhân ma trận
GVHD:

Ts Hà Mạnh Đào

Nhóm - Lớp:

4 – 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 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ư q 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 tố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 tố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 tốn song song.
Minh họa một cách đơn giản, tính tố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 tố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 tốn song song so với các loại hình tính tố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
tố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 q 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.


Mục lục
Giới thiệu chung.........................................................................................................2
Phần I: Mở đầu..........................................................................................................4
1.1.

Giới thiệu về OpenMP và thư viện................................................................4

1.1.1.

OpenMP là gì?.............................................................................................4


1.1.2.

Mơ hình song song OpenMP.......................................................................4

1.1.3.

Tổng quan về API OpenMP........................................................................5

1.1.4.

Cú pháp OpenMP........................................................................................9

Phần 2: Kết quả nghiên cứu...................................................................................13
2.1. Bài toán nhân ma trận......................................................................................13
2.1.1.

Tổng quan về bài toán.............................................................................13

2.1.2.

Thuật toán Fox.........................................................................................14

Phần 3: Kết luận và bài học kinh nghiệm..............................................................22
3.1. Kết quả đánh giá trên ma trận khác nhau........................................................22
3.1.1. Thông số hệ thống....................................................................................22
3.1.2. Thiết lập bài 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ĩ năng đã học.......................................................................23

TÀI LIỆU THAM KHẢO.......................................................................................24

Danh mục hình ảnh
Hình 1. 1 Mơ hình lập trình bộ nhớ chia sẻ
Hình 1. 2 Minh họa mơ hình Fork join của OpenMP
Hình 2. 1 Ví dụ về ma trận tổng quát
Hình 2. 2 Minh họa phép nhân ma trận
Hình 2. 3 Minh họa cách chia ma trận thành các khối ma trận con

6
6
13
14
15


Hình 2. 4 Minh họa q trình dịch vịng các khối trong ma trận theo thuật tốn Fox
Hình 2. 5 Hàm cài đặt Fox hồn chỉnh
Hình 2. 6 Đoạn mã lấy id của luồng hiện hành
Hình 2. 7 Đoạn mã xác định khối cần tính tương ứng với luồng hiện hành
Hình 2. 8 Ba con trỏ tương ứng ơ nhớ đầu tiên trong các ma trận con
Hình 2. 9 Lặp n lần với biến gặp state
Hình 2. 10 Tính giá trị các con trỏ tại A1, B1, B1 tại mỗi state
Hình 2. 11 Thực hiện nhân các khối con và 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 về OpenMP và thư viện
1.1.1. OpenMP là gì?


OpenMP là một giao diện lập trình ứng dụng(API) được định nghĩa bởi một
nhóm các tổ chức phần cứng chuyên dụng và các nhà cung cấp phần mềm.
OpenMP cung cấp một mơ hình lập trình linh động, có thể mở rộng cho các
nhà phát triển trên mơ hình tính tốn song song cho bộ nhớ chia sẻ.



OpenMP hỗ trợ các ngôn ngữ là C/C++ và Fortran trên một lượng rộng các
kiến trúc phần cứng khác nhau. Trong đề tài này chúng tôi sẽ sử dụng
OpenMP trên môi trường C++ để cài đặt và minh họa hiệu suất của thuật toán
nhân ma trận khi làm việc trên hai mơ hình lập trình là tuần tự và song song.

1.1.2. Mơ hình song song OpenMP


Cơ chế đa luồng
● OpenMP thực hiện việc tính tốn song song tuân theo cơ chế đa luồng.
Luồng là một đơn vị thực thi nhỏ nhất của một tiến trình và có thể được
sắp lịch bởi hệ điều hành. Trong một tiến trình có thể có nhiều luồng thực
thi.
– Song song tường minh



● Khơng giống như một số mơ hình lập trình song song được 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 bộ hoạt
động tính tốn song song. Một chương trình song song có thể được xây
dựng trong OpenMP bằng việc chèn thêm các chỉ thị tiền xử lý vào một
chương trình tuần tự bình thường.
– Cơ chế bộ nhớ chia sẻ

Hình 1. 1 Mơ hình lập trình bộ nhớ chia sẻ
● OpenMP được thiết kế cho hệ thống đa nhân chia sẻ bộ nhớ trên các kiến
trúc có thể kể tên như UMA, hay NUMA. Trong OpenMP mọi luồng đều
có thể truy cập đến vùng nhớ tồn cục. Dữ liệu có thể là tồn cục hoặc
riêng tư giữa các luồng. Việc đồng bộ hóa có thể được thực hiện bởi người
lập trình nhưng phần lớn được 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 là một tiến trình đơn thực hiện tuần tự cho
đến khi gặp một đoạn chỉ thị song song sẽ được rẽ nhánh ra thành các
chương trình con, sau khi thực hiện xong thì sẽ lại về một luồng chính.
Fork chỉ q trình rẽ nhánh, Join chỉ quá trình hợp lại.


Hình 1. 2 Minh họa mơ hình Fork join của OpenMP
– Các đoạn song song lồng nhau
● OpenMP các luồng song song tiếp tục tách thành các luồng song song nhỏ
hơn nhằm đẩy mạnh tốc độ tính tốn.
1.1.3. Tổng quan về API OpenMP
– OpenMP gồm các thành phần chính sau:
● Các chỉ 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 chỉ thị biên dịch trong OpenMP
● Chỉ thị biên dịch được sử dụng với các mục đích:
▪ Sinh ra một luồng các chương trình song song
▪ Phân chia các khối lệnh giữa các luồng
▪ Thực hiện tuần tự các đoạn mã được chỉ định
▪ Đồng bộ hóa cơng việc giữa các luồng
●Cú pháp của một chỉ thị tiền xử lý OpenMP trong C++
#pragma omp [Tên chỉ 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 được sử dụng
cho các mục đích sau:
▪ Thiết đặt truy vấn số luồng


▪ Truy vấn id của luồng, số luồng hiện có
▪ Truy vấn chu kỳ đồng hồ và phân giải
–Các biến môi trường
● OpenMP cung cấp các 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 được sử dụng cho các mục đích sau
▪ Thiết đặt số luồng
▪ Chỉ định cách các lần lặp trong vòng lặp được chia ra cho các
luồng
▪ Gán các luồng với các tiến trình
▪ Thiết lập cấu trúc ngăn xếp
–Cấu trúc tổng quát của một đoạn chương trình OpenMP
#include <omp.h>
main () {

int var1, var2, var3;
Đoạn mã tuần tự
.
.
.
Bắt đầu đoạn mã song song bằng chỉ 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ã tuần tự
.
.
}

1.1.4. Cú pháp OpenMP
– Một số chỉ thị tiền xử lý
● parallel: Chỉ thị bắt đầu đoạn code song song
● for: Thực hiện vòng lặp for bên trong vùng song song được chia cho
các luồng
● sections: Xác định các phần mã được chia sẻ cho các luồng
● single: Chỉ định phần mã được thực thi trên một luồng duy nhất

● master: Chỉ ra luồng chính được thực thi của một chương trình
● critical: Chỉ định phần mã là đoạn giới hạn (Đoạn chương trình sử dụng
tài nguyên gang)
● barrier: Tạo thanh chặn ngăn các luồng tiếp tục thực thi cho đến khi tất
cả các luồng khác đã xong
● atomic: Chỉ phần bộ nhớ chỉ được cập nhật duy nhất bởi một luồng tại
một thời điểm
● flush: Chỉ định các luồng có cùng một khung nhìn chung cho bộ nhớ
chia sẻ
● ordered: Chỉ định thứ tự được thực hiện trong vòng lặp for song song
● threadprivate: Chỉ định một biến riêng của luồng
– Các hàm quan trọng
● omp_get_thread_num(): Lấy ra số lượng luồng hiện thời
● omp_get_num_thread(): Lấy ra id của luồng hiện tại


● num_threads(): Chỉ định số luồng thực hiện


Phần 2: Kết quả nghiên cứu
2.1. Bài toán nhân ma trận
2.1.1. Tổng quan về bài toán
– Khái niệm về ma trận và nhân ma trận
Ma trận là một mảng chữ nhật gồm các số, ký hiệu, hoặc biểu thức, sắp
xếp theo hàng và cột mà mỗi ma trận tuân theo những quy tắc định trước. Các
ô trong ma trận được gọi là các phần tử của ma trận. Các phần tử được xác
định bằng hai chỉ số là hàng và cột trong tài liệu này chúng ta dùng hai biến
tương ứng là i, j. Phần tử hang thứ i cột j kí hiệu là aij
Ma trận thường được viết trong dấu ngoặc vng:


Hình 2. 1 Ví dụ về ma trận tổng quát
Trong nhiều bài toán, ma trận là biểu diễn của dữ liệu hoặc các phép biến đổi
trong bài toán đó. Như trong xử lý ảnh ta có ma trận điểm ảnh, trong học máy
ta có ma trận các vector đặc trưng…
Để giải các bài tốn trên thao tác tính toán phố biến nhất được thực hiện là
phép nhân ma trận. Phép nhân ma trận chỉ được thực hiện khi số lượng cột
trong ma trận thứ nhất phải bằng số lượng hàng trong ma trận thứ hai. Ma trận
kết qua được gọi là tích ma trận, có kích cỡ là số hàng của ma trận đầu tiên và
số cột của 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) thì ma
trận kết quả C sẽ có kích thước (m x n). Phần tử Cij được xác định bởi công
thức:


Hình 2. 2 Minh họa phép nhân ma trận
– Độ phức tạp của thuật tốn
● Ma trận kết quả có kích thước n x m
● Để tính tốn một ơ của ma trận kết quả, ta cần k phép nhân do đó độ phức
tạp của thuật tốn là n x m x k
● Đây là độ phức tạp tương đối lớn khi thực hiện tính tốn tuần tự. Đối với
những bài tốn trong trí tuệ nhân tạo, ma trận các vector đặc trưng có thể
lên đến hàng nghìn kéo theo các phép toán cần thực hiện lên đến hàng tỷ.
Một con số không hề nhỏ khi thực hiện trên một máy tính tuần tự. Thời
gian tính tốn có thể lên đến hàng giờ hàng ngày.
● Điều này có thể giải quyết bằng việc phân các cơng việc tính tốn cho các
tiến trình và thực hiện song song. Trên thực tế đã có nhiều phương pháp để
thực hiện điều này, trong đề tài này để minh họa quá trình trên chúng tơi
xin được sử dụng thuật tốn Fox.
2.1.2. Thuật tốn Fox
– Tổng quan về thuật tốn Fox


Fox là thuật tóa nhân ma trận song song thực hiện bằng việc chia ma trận
vuông thành các ma trận con như bàn cờ, mỗi tiến trình sẽ đảm nhiệm việc tính
tốn một ma trận con của ma trận kết quả. Việc phân chia công việc tính tốn và
thực hiện đồng thời trên các 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 trong thuật toán Fox khi thực hiện tuần tự


– Gọi hai ma trận cần nhân là A và B
– Ma trận A và B được chia thành các khối ma trận con

Hình 2. 3 Minh họa cách chia ma trận thành các khối ma trận con
– Ta có thể coi ma trận A, B là ma trận các khối ma trận. Một ma trận
con được xác định thông qua hai chỉ số là hàng và cột tương ứng với i
và 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 trên j đơn vị thứ i, j tính
từ 0. Khởi tạo ma trận C là ma trận 0
– Thuật toán trải qua n bước lặp tại bước lặp thứ k, ma trận khối C ij được
cộng thêm bằng một lượng Aij * Bij. Sau mỗi bước lặp dịch các hàng ở
ma trận A thêm 1 sang phải, dịch các cột ma trận B thêm 1 lên trên.

Hình 2. 4 Minh họa q trình dịch vịng các khối trong ma trận theo thuật toán Fox
– Sau n bước lặp ta thu được ma trận C là ma trận kết quả.
– Thuật toán Fox khi được thực hiện song song
– Các ở bước số 2, thay vì được thực hiện bởi 1 luồng duy nhất các khối
ma trận con được chia cho các luồng con đảm nhận. Mỗi luồng sẽ chịu



trách nhiệm cho việc tính tốn một khối ma trận con trong ma trận kết
quả.
– Trong mơ hình này, việc dịch dịng và cột sẽ khơng được thực hiện tiếp
mà chỉ dịch logic.

Hình 2. 5 Hàm cài đặt Fox hồn chỉnh
– Hàm nhân ma trận nhận vào 3 đối với A, B, C. A và B là hai ma trận
cần nhân, C là ma trận kết quả.
– Giải thích đoạn mã

Hình 2. 6 Đoạn mã lấy id của luồng hiện hành

Hình 2. 7 Đoạn mã xác định khối cần tính tương ứng với luồng hiện hành

Hình 2. 8 Ba con trỏ tương ứng ô nhớ đầu tiên trong các ma trận con

Hình 2. 9 Lặp n lần với biến gặp state


Hình 2. 10 Tính giá trị các con trỏ tại A1, B1, B1 tại mỗi state

Hình 2. 11 Thực hiện nhân các khối con và cộng vào ma trận C
– Một số lưu ý:
– Số luồng thực hiện cần phải là số chính phương và là ước của số phần
tử của ma trận, nếu khơng thuật tốn sẽ khơng hoạt động chính xác.
– Chương trình hồn thiện kèm driver code cho việc đánh giá hiệu năng
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>

#include <omp.h>
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 và bài học kinh nghiệm
3.1. Kết quả đánh giá trên ma trận khác nhau
3.1.1. Thông số hệ thống
– Chương trình được thực thi trên mơi trường Microsoft Studio, với thiết bị
chạy CPU Bộ xử lý Intel® Core™ i5-12500H bộ nhớ đệm 18M, xung tối đa
4,50 GHz, 12 lõi 16 luồng.
3.1.2. Thiết lập bài toán

– Để tận dụng được tối đa hiệu suất CPU, trong chương trình này sẽ thiết lập số
luồng là 16, kích thước của các ma trận là bội số của số luồng (Đảm bảo khối
lượng công việc trong các luồng khác nhau).
3.1.3. Thống kê thời gian
– Coi phần mã tuần tự là các dịng thiết lập q trình trong q trình nhân ma
trận, ta lấy 100 đơn vị trên 1 dòng. Ở đây ta có 13 dịng.
– Coi phần mã song song là phần nhân ma trận, ta lấy n * n * 100 đơn vị với n
là kích thước ma trận.
– Hệ số tăng tốc Amdahl’s được tính theo cơng thức:
Speedup = 1 / (S + P / N)
S: Tỉ lệ mã bắt buộc phải tuần tự
P: Tỉ lệ mã song có thể song song hóa
N: Số luồng
– Sau khi chạy thử 6 lần với kích thước các ma trận khác nhau ta được bảng
thống kê:
– Sau khi chạy thử 6 lần với kích thước các ma trận khác nhau ta được 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 tuần
tự (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ế

1

4

0.00614

0.00001

1300

1600

2.0714285

0.00162

2


64

0.01217

0.00092

1300

4096

3.4678663

0.07559

3

128

0.02174

0.0218

1300

16384

7.6092943

1.00275


4

160

0.01681

0.02128

1300

25600

9.2758620

1.26591

5

1600

1.69029

19.61307

1300

2560000

15.879107


11.6033


6

3200

16.61166

260.3794

1300

1024000

15.969593

15.6744

3.1.4. Nhận xétn xét
–Ở các lần thử nghiệm 1, 2, 3, 4 do kích thước ma trận khơng đáng kể và có thể
do thước ma trận khơng đáng kể và có thể do ước lượng đoạn mã tuần tự và
song song chỉ mang tính xấp xỉ nên dẫn đến sự lệch nhau khá nhiều giữa hệ số
tăng tốc thực tế và hệ số tăng tốc theo Amdahl’s.
–Sang đến lần thử nghiệm 5 và 6 khi kích thước ma trận đã là hàng nghìn các con
số ước tính mới bắt đầu gần nhau hơn và hệ số tăng tốc giữa thực tế và ước
tính có vẻ đã tiến gần tới số luồng.
–Điều này còn cho thấy sự chênh lệch về hiệu suất lớn giữa tính tốn song song
và tính tốn tuần tự trong những bài tốn có khối lượng tính tốn khổng lồ.

Khi ở lần thử nghiệm 6 với kích thước ma trận là 3200 x 3200. Tính tốn song
song cho ra kết quả chỉ với 16 giây trong khi đó ở tính tốn tuần tự mất tận
gần 4 phút để cho ra output tương đương.
3.2. Các kiến thức kĩ năng đã học
–Qua đề tài trên chúng ta đã có thể phần nào thấy được sức mạnh vượt trội của
tính tốn song song trong các bài toán lớn. Đây là tiền để cũng như động lực to
lớn để nhóm tiếp tục nghiên cứu các bài tốn khác trên nền tảng tính toán song
song sau này.



×