2013-03-25 24 views
7

Thư viện lực đẩy có thể được sử dụng để sắp xếp dữ liệu. Cuộc gọi có thể trông như thế này (với một phím và một véc tơ giá trị):CUDA: cách sử dụng lực đẩy :: sort_by_key trực tiếp trên GPU?

thrust::sort_by_key(d_keys.begin(), d_keys.end(), d_values.begin()); 

gọi trên CPU, với d_keysd_values là trong bộ nhớ CPU; và phần lớn việc thực hiện xảy ra trên GPU.

Tuy nhiên, dữ liệu của tôi đã có trên GPU? Làm thế nào tôi có thể sử dụng thư viện Thrust để thực hiện phân loại hiệu quả trực tiếp trên GPU, tức là, để gọi hàm sort_by_key từ hạt nhân?

Ngoài ra, dữ liệu của tôi bao gồm các khóa là unsigned long long int hoặc unsigned int và dữ liệu luôn là unsigned int. Làm thế nào tôi nên thực hiện cuộc gọi đẩy cho các loại này?

Trả lời

6

Như đã nêu trong câu hỏi Tài trợ được liên kết, bạn không thể gọi Thrust từ một hàm CUDA (ví dụ: __device__ hoặc __global__). Tuy nhiên, điều này không có nghĩa là bạn không thể sử dụng dữ liệu bạn đã có trong bộ nhớ thiết bị với Thrust. Thay vào đó, bạn gọi các hàm Thrust mong muốn từ máy chủ bằng cách sử dụng các vectơ Thrust gói dữ liệu thô của bạn. ví dụ.

//raw pointer to device memory 
unsigned int * raw_data; 
unsigned int * raw_keys; 
//allocate device memory for data and keys 
cudaMalloc((void **) &raw_data, N_data * sizeof(int)); 
cudaMalloc((void **) &raw_keys, N_keys * sizeof(int)); 

//populate your device pointers in your kernel 
kernel<<<...>>>(raw_data, raw_keys, ...); 

... 

//wrap raw pointer with a device_ptr to use with Thrust functions 
thrust::device_ptr<unsigned int> dev_data_ptr(raw_data); 
thrust::device_ptr<unsigned int> dev_keys_ptr(raw_keys); 

//use the device memory with a thrust call 
thrust::sort_by_key(d_keys, d_keys + N_keys, dev_data_ptr); 

Bộ nhớ thiết bị trỏ đến bởi raw_dataraw_keys vẫn còn trong bộ nhớ điện thoại khi bạn bọc chúng lại bằng Thrust::device_ptr, vì vậy khi bạn đang gọi hàm Thrust từ máy chủ, nó không phải sao chép bất kỳ bộ nhớ từ máy chủ đến thiết bị hoặc ngược lại. Tức là, bạn sắp xếp trực tiếp trên GPU, sử dụng bộ nhớ thiết bị; chi phí duy nhất bạn sẽ có là trong việc khởi chạy hạt nhân Thrust (s) và gói các con trỏ thiết bị thô.

Và dĩ nhiên, bạn có thể nhận con trỏ liệu của bạn trở lại nếu bạn cần phải sử dụng chúng trong một hạt nhân CUDA thường xuyên sau:

unsigned int * raw_ptr = thrust::raw_pointer_cast(dev_data_ptr); 

Đối với sử dụng một trong hai unsigned long long int hoặc unsigned int như phím của bạn với dữ liệu đó là unsigned int, đây không phải là một vấn đề, như Thrust là templated. Tức là chữ ký cho sort_by_key

template<typename RandomAccessIterator1 , typename RandomAccessIterator2 > 
void thrust::sort_by_key(   
    RandomAccessIterator1 keys_first, 
    RandomAccessIterator1 keys_last, 
    RandomAccessIterator2 values_first) 

có nghĩa là bạn có thể có các loại khác nhau cho khóa và dữ liệu. Miễn là tất cả các loại khóa của bạn đều đồng nhất với một cuộc gọi nhất định, Lực đẩy sẽ có thể suy ra các loại tự động và bạn sẽ không phải làm bất cứ điều gì đặc biệt. Hy vọng điều đó có ý nghĩa

+0

@ user1760748: Câu trả lời dưới đây có thỏa mãn bạn không? Nếu không, vui lòng cho biết có vấn đề với nó hay không ... – einpoklum

Các vấn đề liên quan