You are on page 1of 10

BỘ GIÁO DỤC VÀ ĐÀO TẠO

TRƯỜNG ĐẠI HỌC LẠC HỒNG


***

Họ và tên: Nguyễn Lê Minh Hòa


Lớp: 22CC911

BÀI THU HOẠCH


MÔN:
TÍNH TOÁN SONG SONG VÀ PHÂN TÁN

Giảng viên: PGS.TS TRẦN VĂN LĂNG

Đồng Nai – Năm 2022

Bài cáo môn Tính toán song song và phân tán 1


MỤC LỤC

1. Giới thiệu ..................................................................................................................... 4

2. Tổng quan kiến thức .................................................................................................. 4

2.1. OpenMP ..........................................................................................................4

2.2. Thư viện Runtime ...........................................................................................4

2.3. Biên dịch chương trình ...................................................................................5

2.4. Cài đặt thư viện liên quan .............................................................................. 5

3. Viết chương trình tính tổng các phần tử trong mảng ............................................ 7

Bài cáo môn Tính toán song song và phân tán 2


HÌNH ẢNH
Hình 1 Số luồng trên máy tính ................................................................................ 5
Hình 2 Chọn GPU để tăng tốc xử lý ....................................................................... 5
Hình 3 Kiểm tra câu lệnh Automagic trên môi trường Google Colab ................... 6
Hình 4 Kiểm tra và cài đặt các phần mềm hỗ trợ ................................................... 6
Hình 5 Cài đặt công cụ biên dịch ............................................................................ 6
Hình 6 Kiểm tra số lượng thiết bị GPU .................................................................. 7
Hình 7 Chương trình dùng CPU để tính toán ......................................................... 9
Hình 8 Kiểm tra hoạt động của GPU .................................................................... 10

Bài cáo môn Tính toán song song và phân tán 3


1. Giới thiệu
Google Colab hỗ trợ rất nhiều thư viện và những công cụ để biên diện code,
trong đó công cụ biên dịch GCC dịch code với ngôn ngữ C/C++ trên chính tài nguyên
máy tính của Google. Với tài khoản miễn phí, thời gian người dùng có thể sử dụng tài
nguyên GPU và TPU lên tới 12 tiếng, đối với tài khoản trả phí, thời gian được kéo dài
hơn cũng như nhận được cấu hình mạnh hơn. Nhằm tận dụng nguồn tài nguyên miễn
phí đến từ Google, chương trình song song bằng OpenMP được viết bằng ngôn ngữ C
nhằm khai thác được GPU của hệ thống máy tính của Google Colab. Chương trình này
sẽ áp dụng cho việc tính toán tổng của một mảng có nhiều phần tử.

2. Tổng quan kiến thức


2.1. OpenMP
Như chúng ta đã thấy công nghệ CPU ngày càng phát triển, nhưng tốc độ CPU
đang dần tăng chậm lại, thay vào đó công nghệ GPU ngày càng được nâng cấp và
được áp dụng rộng rãi trong các ngành công nghệ thông tin, hàng không, dịch vụ ... để
có thể nhanh chóng tính toán, xử lý và giải quyết lượng dữ liệu đồ sộ trong xã hội hiện
đại hóa.
Ngôn ngữ OpenMP đã và đang thêm các tính năng để khai thác thiết bị phần
cứng tối đa, nó có thể là GPU, FPGA, v.v. Bài toán tính tổng được viết trên phiên bản
OpenMP mới nhất hiện tại là v5.2
2.2. Thư viện Runtime
OpenMP thư viện runtime. Chúng được sử dụng cho nhiều mục đích như: sửa
đổi hoặc kiểm tra số lượng luồng, phát hiện xem ngữ cảnh thực thi có nằm trong vùng
song song không, có bao nhiêu bộ xử lý trong hệ thống hiện tại, ...
Các định nghĩa hàm nằm trong thư viện <omp.h> trong C/C ++ và trong FORTRAN
trong mô-đun omp_lib. Một số hàm hữu ích thường dùng:
● omp_get_num_threads ()
● omp_get_thread_num ()
● omp_get_wtime ()
%%writefile sample.c

#include <omp.h>

Bài cáo môn Tính toán song song và phân tán 4


#include <stdio.h>
int main(int argc, char argv[]){
int omp_rank;
#pragma omp parallel
{
omp_rank = omp_get_thread_num();
printf("Hello world! by thread %d\n", omp_rank);
}
}
Thực hiện biên dịch đoạn chương trình trên, kết quả như hình 1, số luồng trên máy
tính này là 2.

Hình 1 Số luồng trên máy tính

2.3. Biên dịch chương trình


Để sử dụng OpenMP, thêm lựa chọn cấu hình này để có thể biên dịch chương
trình.
GNU: -fopenmp
Example: !gcc sample.c -fopenmp -o sample
2.4. Cài đặt thư viện liên quan
Sau khi đăng nhập vào Google Colab, người dùng cần chọn cấu hình tăng tốc
phần cứng (Hardware Accelerator) là GPU như hình 2.

Hình 2 Chọn GPU để tăng tốc xử lý

Kiểm tra và cài đặt một số thư viện để đáp ứng trước khi thực hiện chương trình.

Bài cáo môn Tính toán song song và phân tán 5


Hình 3 Kiểm tra câu lệnh Automagic trên môi trường Google Colab

Để linh hoạt sử dụng câu lệnh trên Google Colab, ta có thể sử dụng câu lệnh
của Automagic (hình 3), ngoài ra có thể sử dụng dấu “!” trước các câu lệnh trên các
Cell để thực thi trực tiếp câu lệnh giống như trên Linux.
Hình 4 thể hiện việc kiểm tra và các phần mềm mới nhất được hỗ trợ trên hệ
thống Google Colab.

Hình 4 Kiểm tra và cài đặt các phần mềm hỗ trợ

Để tránh những lỗi không mong muốn phát sinh từ quá trình biên dịch code,
báo cáo này sử dụng công cụ GCC-10 để biên dịch, và cài thêm thư viện offload để
giảm tải việc xử lý từ host sang thiết bị đầu xa (hình 5).

Hình 5 Cài đặt công cụ biên dịch

Bài cáo môn Tính toán song song và phân tán 6


Hình 6 Kiểm tra số lượng thiết bị GPU

Sau khi cài đặt chức năng tăng tốc phần cứng là GPU, tiến hành kiểm tra bằng
ngôn ngữ OpenMP như sau:
● Viết chương trình num_device.c
● Biên dịch thành file num_device và thực thi file
● Mong đợi kết quả lớn hơn hoặc bằng 1 tương ứng với số lượng GPU có
trên hệ thống máy tính

3. Viết chương trình tính tổng các phần tử trong mảng


%%writefile summ_2array.c
#include <omp.h>
#include <stdio.h>
#include <time.h>
#define SIZE 1000000
Thêm thư viện vào chương trình và định nghĩa mảng của phần tử (SIZE) là
1000000.
Trong hàm main, định nghĩa các biến tham số và gán giá trị vào từng mảng. Gọi
hàm #pragma omp <target data> <map> đến thiết bị là GPU, với:
● <target data> là gửi dữ liệu tính toán xuống thiết bị đích
● <map> là dữ liệu được đọc và ghi trong bộ tính toán song song của offload
■ map(to: ...) là dữ liệu chỉ đọc trong bộ tính toán song song, ở đây là biến
array_sum[0:SIZE], dùng để đọc giá trị trong mảng phục vụ cho việc tính
toán

Bài cáo môn Tính toán song song và phân tán 7


■ map(from: ...) là dữ liệu chỉ viết trong bộ tính toán song song, ở đây là
biến sum dùng để tính toán từng tổng các phần tử trong mảng
Việc chỉ định sử dụng các biến đúng cách sẽ làm giảm bớt việc giao tiếp giữa
máy chủ và thiết bị, giúp tiết kiệm tài nguyên của GPU để có thể sử dụng cho các tác
vụ xử lý khác.
Đoạn code sau đây được dùng để tính toán tổng của các phần tử trong mảng sử
dụng CPU được mô tả như sau:
● Đầu vào: Số phần tử mảng có 100000 phần tử với giá trị tăng dần từ 0 đến
99999.
● Đầu ra: Kết quả tổng của toàn bộ mảng và thời gian thực thi chương trình của
CPU.
%%writefile sum_array.c
#include <omp.h>
#include <stdio.h>
#include <time.h>
#define SIZE 1000000

int main()
{
long array_sum[SIZE];
long sum = 0;
const long N=10000;
double tb = 0, te = 0, t = 0;
for (long i=0; i<N; i++){
array_sum[i]=i;
}
float time1,time2;
time1=clock();

tb = omp_get_wtime();
printf("Get num of CPU = %d\n", omp_get_max_threads());
omp_set_num_threads(2);
printf("Get num of CPU = %d\n", omp_get_max_threads());
printf("Get num of GPU device = %d\n", omp_get_num_devices());
#pragma omp parallel for
for (int i =0; i<N; i++)
{
sum += array_sum[i];
}
long final_expect = N*(N-1)/2;
printf("Sum of 2 array_sum = %ld, expect sum = %ld\n", sum, N*(N-1)/2);
time2=clock();
te = omp_get_wtime();
t = te - tb;
printf("Time of code by C = %1f ms\n", (time2-time1)/1000);
printf("Time of kernel by OpenMP = %1f ms\n", t*1000);
return 0;
}
Thời gian đạt được sau khi biên dịch và chạy chương trình trên là khoảng 26 ms.

Bài cáo môn Tính toán song song và phân tán 8


Hình 7 Chương trình dùng CPU để tính toán

Thay đổi một số câu lệnh để chương trình hoạt động trên GPU như bên dưới.
Đầu ra và đầu vào của chương trình này được mô tả như sau:
● Đầu vào: Số phần tử mảng có 100000 phần tử với giá trị tăng dần từ 0 đến
99999.
● Đầu ra: Kết quả tổng của toàn bộ mảng và thời gian thực thi chương trình của
GPU.
Thay thế đoạn lệnh từ:
#pragma omp parallel for
for (int i =0; i<N; i++)
{
sum += array_sum[i];
}
trở thành:
#pragma omp target data map(to:array_sum[0:SIZE]), map(from: sum)
{
for (int i =0; i<N; i++)
{
sum += array_sum[i];
}
Chương trình hoàn chỉnh:
%%writefile summ_2array.c
#include <omp.h>
#include <stdio.h>
#include <time.h>
#define SIZE 1000000

int main()
{
long array_sum[SIZE];
long sum = 0;
const long N=100000;
double tb = 0, te = 0, t = 0;
for (long i=0; i<N; i++){
array_sum[i]=i;
}
float time1,time2;
time1=clock();

tb = omp_get_wtime();

Bài cáo môn Tính toán song song và phân tán 9


#pragma omp target data map(to:array_sum[0:SIZE]), map(from: sum)
{
for (int i =0; i<N; i++)
{
sum += array_sum[i];
}
}
long final_expect = N*(N-1)/2;
printf("Sum of 2 array_sum = %ld, expect sum = %ld\n", sum, N*(N-1)/2);
time2=clock();
te = omp_get_wtime();
t = te - tb;
printf("Time of code by C = %1f ms\n", (time2-time1)/1000);
printf("Time of kernel by OpenMP = %1f ms\n", t*1000);
return 0;
}
Trong đoạn code trên có sử dụng hàm omp_get_wtime() để lấy được thời gian
trước và sau khi thực thi chương trình.
nvprof là câu lệnh của NVIDIA dùng để kiểm tra thông số của GPU sau khi
thực hiện đoạn chương trình trên. Câu lệnh này chỉ dùng khi máy tính có GPU hoạt
động, vì vậy người dùng cần đảm bảo máy tính đã được bật sẵn GPU trước đó.

Hình 8 Kiểm tra hoạt động của GPU

Kết quả: So sánh kết quả ở hình 7 và hình 8, chương trình được thực hiện trên
CPU trong chậm hơn gần gấp 10 lần so với thời gian thực hiện ở GPU, khoảng 2.3 ms.

Bài cáo môn Tính toán song song và phân tán 10

You might also like