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
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 CUDAKhông hỗ trợ render textureBandwidth và độ trễ giữa CPU và GPU dẫn đến hiện tượng thắt nút cổ chaiChỉ 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 (http://www.nvidia.com/object/cuda_gpus.html) CUDA kết hợp với OpenGLCUDA OpenGL PipelineVấn đề bộ nhớ khi lập trình với CUDABở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 GPUViệ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ếnfloat *h_dataA, *h_dataB, *h_resultC;float *d_dataA, *d_dataB, *d_resultC;//Cấp phát cho bộ nhớ chương trìnhh_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 GPUCUDA_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 GPUCUDA_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ínhCUDA_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 threadmultiplyNumbersGPU<<<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ệcCUDA_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 GPUViết một ứng dụng demo CUDAChươ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 WinAPPDownload file CUDA_VS_Wizard_W32.2.0.zip để dùng wizard tạo 1 chương trình CUDA Hello worldViệ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.cuHà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.cppSource code chương trình nằm trong file Demo.rar . trợ CUDA có thể vào trang sau đây để xem (http://www.nvidia.com/object /cuda_ gpus.html) CUDA kết hợp với OpenGLCUDA OpenGL PipelineVấn đề bộ nhớ khi lập trình. 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