Professional Documents
Culture Documents
3. Viết chương trình tính tổng các phần tử trong mảng ............................................ 7
#include <omp.h>
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.
Để 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.
Để 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).
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
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.
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();
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.