Môi trường phát triển đầu tiên cho OpenCL

Sau nhiều ngày chờ đợi, từ hôm nay, giới lập trình song song trên GPU lại có thêm một công cụ mạnh mẽ trong tay, đó là môi trường phát triển cho OpenCL, do NVIDIA phát hành. Bộ môi trường phát triển này bao gồm trình điều khiển thiết bị riêng cho OpenCL chạy trên các GPU của NVIDIA, và bộ OpenCL SDK.

Thông tin chi tiết đến từ trang web của NVIDIA:

http://www.nvidia.com/object/io_1240224603372.html
http://www.nvidia.com/object/cuda_opencl.html

Để tham gia dùng thử bộ OpenCL SDK này, mọi người có thể tham gia chương trình “NVIDIA’s GPU Computing Registered Developer Program” bằng cách đăng ký ở đây:

http://nvdeveloper.nvidia.com/content/GPUComputingDeveloperApplication/
frmDeveloperRegistration.asp

Bộ công cụ phát triển này đang còn ở giai đoạn sơ khai (Alpha Test) nên chỉ bao gồm các chức năng quan trọng nhất nêu trong đặc tả chuẩn OpenCL 1.0 của tổ chức Khronos.

Lập trình trên OpenCL là một chủ đề mới khá thú vị mà tôi hy vọng sẽ có dịp trao đổi nhiều hơn khi có thêm thời gian 🙂

Komrade – Thư viện C++ cho CUDA

Hôm nay NVIDIA chính thức công bố thư viện lập trình C++ cho CUDA đầu tiên, với tên gọi Komrade.

http://code.google.com/p/komrade/

Với thư viện này, NVIDIA đã cung cấp một công cụ tuyệt vời cho những ai yêu thích vẻ đẹp đơn giản của lập trình định hướng đối tượng, đặc biệt là các tín đồ C++ giáo, cùng với sức mạnh của GPU trong tính toán song song. Sau đây là một chương trình hoàn chỉnh để tính tổng của 100 số ngẫu nhiên trên GPU, mà tôi mạn phép sao chép từ trang chính của Komrade.

[sourcecode language=”cpp”]
#include <komrade/host_vector.h>
#include <komrade/device_vector.h>
#include <komrade/generate.h>
#include <komrade/reduce.h>
#include <komrade/functional.h>
#include <cstdlib>

int main(void)
{
// generate random data on the host
komrade::host_vector h_vec(100);
komrade::generate(h_vec.begin(), h_vec.end(), rand);
// transfer to device and compute sum
komrade::device_vector d_vec = h_vec;
int x = komrade::reduce(d_vec.begin(),
d_vec.end(),
komrade::plus());
return 0;
}

[/sourcecode]

Trong hàm main() ở đoạn chương trình trên, rõ ràng chúng ta không cần quan tâm gì đến chuyện khởi động thiết bị (GPU), rồi cấp phát bộ nhớ trên RAM và trên bộ nhớ toàn cục của GPU, sao chép dữ liệu từ RAM vào phần bộ nhớ trên GPU, kích hoạt kernel để tính toán, sau cùng lấy dữ liệu từ GPU trả trở về cho CPU, như thường thấy trong lập trình CUDA.

Các bạn thử chạy chương trình trên với số lượng các số ngẫu nhiên không phải là 100, mà 1000, hay 10000 coi nó có nhanh hơn phiên bản do các bạn tự sáng tác ra, hay tìm được đâu đó trên NET 🙂 không?

Komrade chỉ dùng được với CUDA 2.2 trở lên. Phiên bản này với rất nhiều cải tiến mới mẻ sẽ được công bố chính thức một ngày không xa 🙂 . Hiện tại các bạn có thể đăng ký và dùng thử ở đây: http://www.nvidia.com/object/cuda_get.html (tìm cụm từ CUDA 2.2 Beta).

Công bố CUDA 2.1

CUDA  đã có phiên bản mới 2.1.  Những cải tiến chính trong phiên bản này là:

  • Hỗ trợ một loạt các chip đồ họa mới của NVIDIA theo danh sách ở đây:
    • http://www.nvidia.com/object/cuda_learn_products.html
  • Hỗ trợ các card siêu máy tính Tesla trên hệ điều hành Windows Vista 32 và 64 bit.
  • Hỗ trợ hệ điều hành Linux Open SUSE 11.0 32 và 64 bit.
  • Hỗ trợ Visual Studio 2008 SP1loại bỏ hỗ trợ cho Visual Studio.NET 2003.
  • Bổ sung hàm thực thi cuModuleLoadDataEx cho mô hình máy ảo PTX JIT.
  • Tăng cường tính tương hỗ với thư viện DirectX 9 với hàm cuD3D9ResourceGetMappedArray.
  • Bổ sung tính hỗ trợ cho DirectX 10 với một loạt hàm mới:

– cuD3D10GetDevice
– cuD3D10CtxCreate
– cuD3D10RegisterResource
– cuD3D10UnregisterResource
– cuD3D10MapResources
– cuD3D10UnmapResources
– cuD3D10ResourceSetMapFlags
– cuD3D10ResourceGetMappedArray
– cuD3D10ResourceGetMappedPointer
– cuD3D10ResourceGetMappedSize
– cuD3D10ResourceGetMappedPitch
– cuD3D10ResourceGetSurfaceDimensions

  • Hỗ trợ tốt hơn cho OpenGL bằng việc sửa chữa một bug quan trọng. Giờ đây hệ thống chỉ copy các vùng đệm dùng chung qua bộ nhớ RAM khi CUDA và OpenGL chạy trên các GPU khác nhau.

Những tồn tại vẫn chưa giải quyết được bao gồm các vấn đề sau đây.

* Trên hệ điều hành Vista:

  • Để chạy CUDA trên GPU không phải loại TESLA thì hoặc phần Windows desktop phải được mở rộng cho GPU đó, hoặc là GPU đó phải được thiết lập như một PhysX GPU.
  • Các kernel riêng lẻ bị giới hạn bởi khoảng thời gian thực thi 2 giây trên Windows Vista. Các kernel chạy lâu hơn 2 giây sẽ làm kích hoạt cơ chế Timeout Detection and Recovery (TDR). Thông tin chi tiết xem ở đây: http://www.microsoft.com/whdc/device/display/wddm_timeout.mspx.
  • Chương trình CUDA Profiler không hỗ trợ sự kiện đếm hiệu năng (performance counter event) trên Windows Vista. Tất cả các cấu hình profiler có liên quan đến sự kiện này sẽ bị bỏ qua.
  • Trên Windows Vista,  tất cả các thao tác copy vùng nhớ không đồng bộ (asynchronous memory copies) sẽ không hỗ trợ cơ chế chồng lấp thời gian với GPU. Nói cách khác, giá trị của biến CU_DEVICE_ATTRIBUTE_GPU_OVERLAP sẽ là 0 trên mọi thiết bị.
  • Kích thước vùng nhớ lớn nhất có thể cấp phát được bằng hàm cudaMalloc trên bộ nhớ của một GPU bị giới hạn bởi (Kích thước bộ nhớ hệ thống theo MB – 512 MB ) / 2.

* Trên hệ điều hành XP:

  • Các kernel riêng lẻ bị giới hạn bởi khoảng thời gian thực thi 5 giây trên các GPU có gắn kết với màn hình hiển thị đồ họa. Các kernel chạy lâu hơn khoảng thời gian này sẽ gây ra lỗi trả về bởi trình điều khiển thiết bị CUDA hoặc trình thực thi CUDA. Tuy nhiên các GPU không nối kết với màn hình sẽ không bị ảnh hưởng bới giới hạn này, do vậy một trong những cách sử dụng CUDA trên Windows XP tiện lợi nhất là sử dụng một card đồ họa có cấu hình vừa phải để nối kết với màn hình, phục vụ cho việc hiển thị, còn phần tính toán song song chính sẽ được thực hiện trên một GPU thứ hai không nối với màn hình, có khả năng tính toán mạnh hơn nhiều so với GPU thứ nhất.

* Các vấn đề chung cho cả XP và Vista:

  • Thứ tự liệt kê GPU trên các hệ thống đa GPU là không xác định và có thể thay đổi trong các phiên bản CUDA kế tiếp. Lập trình viên cần liệt kê tất cả các GPU chạy được CUDA có trong từng hệ thống máy tính và chọn lựa những GPU thích hợp nhất cho ứng dụng của mình.
  • Các ứng dụng cố sử dụng quá nhiều vùng nhớ trên thiết bị có thể làm phát sinh lỗi CUDA_ERROR_OUT_OF_MEMORY. Nếu lỗi này xảy ra, CUDA Context sẽ được đặt vào trạng thái có lỗi, cần phải được hủy đi và tạo lại nếu ứng dụng gây lỗi muốn tiếp tục sử dụng CUDA.
  • Hàm Malloc có thể không thực thi được do hết không gian vùng nhớ ảo. Giới hạn về không gian địa chỉ vùng nhớ này đã được Microsoft sửa chữa trong một bản vá lỗi gần đây: http://support.microsoft.com/kb/940105. Windows Vista SP1 đã có chứa bản vá lỗi này.
  • Khi hai GPU chạy trong chế độ SLI, chỉ có một GPU là dùng được để chạy các chương trình CUDA.
  • CUDA chỉ có thể biên dịch được với Microsoft Studio Visual 8.0 khi bản Service Pack 1 của phần mềm này được cài đặt. Lý do là có một số file header của Windows C++ sẽ gây ra lỗi khi được xử lý bởi cudafe nếu không có SP1.
  • Chế độ biên dịch ngầm định cho mã thực thi trên CPU là C++. Nếu mọi người muốn dùng lại chế độ biên dịch ngầm định như ở các phiên bản trước đây của CUDA, xin vui lòng dùng tùy chọn –host-compilation=c.
  • Để đạt được hiệu năng tối đa khi sử dụng các kích thước đa byte để truy cập cùng một dữ liệu, hãy gộp các thao tác tải/lưu kề nhau càng nhiều càng tốt thay vì dung cách truy cập kiểu union trong C hay truy cập từng byte riêng lẻ. Việc truy cập dữ liệu qua union có thể làm cho trình biên dịch giành thêm vùng nhớ cho đối tượng dữ liệu đó, và truy cập riêng lẻ từng byte một có thể dẫn đến việc truy cập không hợp nhất. Các điểm yếu này của trình biên dịch sẽ được cải thiện trong tương lai.