Tải bản đầy đủ (.doc) (4 trang)

Lập trình GPU và CUDA

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 (112.02 KB, 4 trang )

GPU là gì?
GPU viết tắt của Graphic Processing Unit (còn gọi là visual processing unit) là một con chip được
thiết kế chuyên môn hóa trong việc tính toán nhanh và thay thế bộ nhớ nhằm mục đích tăng tốc
việc xây dựng hình ảnh trong bộ nhớ màn hình để thể hiện lên màn hình. GPU có thể được tích
hợp trên card màn hình, mainboard, hoặc CPU.
CUDA là gì?
CUDA viết tắt của Compute Unified Device Architecture là một kiến trúc tính toán song song
được phát triển bởi NVIDIA. CUDA là động cơ tính toán trong các GPU mà lập trình viên có thể
truy xuất thông qua các ngôn ngữ lập trình phổ biến. Không giống như CPU, GPU tập trung tính
toán đồng thời nhiều luồng một cách chậm rãi hơn là tính toán nhanh chóng một luồng
Ưu điểm của CUDA trên GPU sử dụng graphic API
Đọc rải rác: code có thể được đọc từ địa chỉ bất kỳ trong bộ nhớ.
Chia sẻ bộ nhớ: CUDA sử dụng một bộ nhớ chia sẻ nhanh chung cho các luồng xử lý.
Đọc và ghi dữ liệu trên GPU nhanh chóng.
Hỗ trợ tính toán số nguyên và các phép toán trên bit.
Hạn chế của CUDA
Không hỗ trợ render texture
Bandwidth và độ trễ giữa CPU và GPU dẫn đến hiện tượng thắt nút cổ chai
Chỉ hỗ trợ trên các card đồ họa NVIDIA từ series Geforce8 trở lên. Đề xem danh sách các card đồ
họa có hổ trợ CUDA có thể vào trang sau đây để xem
( />CUDA kết hợp với OpenGL
CUDA OpenGL Pipeline
Vấn đề bộ nhớ khi lập trình với CUDA
Bởi vì nhân CUDA chỉ có thể truy xuất vùng nhớ dành riêng cho GPU, nên khi sử dụng, cần phải
cấp phát bộ nhớ cho chương trình và trên GPU
Việc cấp phát bộ nhớ cho chương trình khi lập trình với CUDA tương tự như trong một chương
trình bình thường. Còn việc cấp phát bộ nhớ trên GPU được thực hiện thông qua hàm
cudaMalloc(void **ppData, int numBytes).
Ví dụ:
//Khai báo biến
float *h_dataA, *h_dataB, *h_resultC;


float *d_dataA, *d_dataB, *d_resultC;
//Cấp phát cho bộ nhớ chương trình
h_dataA = (float *)malloc(sizeof(float) * MAX_DATA_SIZE);
h_dataB = (float *)malloc(sizeof(float) * MAX_DATA_SIZE);
h_resultC = (float *)malloc(sizeof(float) * MAX_DATA_SIZE);
//Cấp phát cho GPU
CUDA_SAFE_CALL( cudaMalloc( (void **)&d_dataA, sizeof(float) *
MAX_DATA_SIZE) );
CUDA_SAFE_CALL( cudaMalloc( (void **)&d_dataB, sizeof(float) *
MAX_DATA_SIZE) );
CUDA_SAFE_CALL( cudaMalloc( (void **)&d_resultC , sizeof(float) *
MAX_DATA_SIZE) );
Copy dữ liệu sang và từ bộ nhớ trên GPU
//copy dữ liệu từ bộ nhớ chương trình chính sang bộ nhớ trên GPU
CUDA_SAFE_CALL( cudaMemcpy(d_dataA, h_dataA, sizeof(float) *
dataAmount, cudaMemcpyHostToDevice) );
//copy dữ liệu từ bộ nhớ trên GPU sang bộ nhớ chương trình chính
CUDA_SAFE_CALL( cudaMemcpy(h_resultC, d_dataA, sizeof(float) *
dataAmount, cudaMemcpyDeviceToHost) );
Gọi thực hiện hàm tính toán chung cho tất cả các thread
multiplyNumbersGPU<<<blockGridRows, threadBlockRows>>>(d_dataA,
d_dataB, d_resultC);
Gọi hàm này để chờ cho đến khi các thread thực hiện xong công việc
CUDA_SAFE_CALL( cudaThreadSynchronize() );
Because CUDA kernels can only access memory dedicated to the GPU, we will need to seperately
allocate memory space both on the host machine, and on the GPU
Viết một ứng dụng demo CUDA
Chương trình tạo particle , ban đầu tất cả các hạt sẽ đều nằm ở vị trí (0,0,0) trong không
gian 3 chiều, sau 1 giây hoặc sau khi người dùng nhấn phím c thì các hạt này sẽ lan ra theo
mặt phẳng xOz, khi lan ra đến 1 mức nào đó thì tất cả các hạt lại quay về vị trí cũ (0,0,0).

Tạo một CUDA WinAPP
Download file CUDA_VS_Wizard_W32.2.0.zip để dùng wizard tạo 1 chương trình CUDA Hello
world
Việc sử dụng Wizard sẽ giúp chúng ta cấu hình sẵn cho project để chạy được chương trình, như
cấu hình compiler, cấu hình các additional Directory (thư mục chứa file include, file lib).
Khi dùng wizard để tạo, ban đầu sẽ có sẵn 2 file readme.txt và sample.cu. Đổi tên file sample này
thành firework.cu.
Tạo thêm 1 file main.cpp để chạy chương trình chính, trong hàm keyprocess hoặc hàm
timercallback sẽ gọi đến hàm ComputeCoor trong file firework.cu
Hàm ComputeCoor sẽ chép dữ liệu từ bộ nhớ chương trình sang bộ nhớ trên GPU để chuẩn bị cho
việc tính toán, sau đó gọi hàm kernel. Hàm kernel là hàm chạy trên GPU, hàm này chỉ thực hiện
việc đơn giản là cộng giá trị x cho sin(i*2*PI/numofThreads)*0.1 và cộng z cho
cos(i*2*PI/numofThreads)*0.1 để các hạt lan đều ra thành vòng tròn. Hàm ComputeCoor sau khi
thực hiện xong (sau khi hàm CUDA_SAFE_CALL( cudaThreadSynchronize() ); kết thúc) thì sẽ
chép dữ liệu từ bộ nhớ trên GPU sang bộ nhớ chương trình để chương trình chính thực hiện việc
vẽ các hạt.
Số lượng hạt được define trong file main.cpp
Source code chương trình nằm trong file Demo.rar

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×