2012-03-21 41 views
6

Tôi có đoạn mã (kernel) sau đây.cấp phát bộ nhớ bên trong hạt nhân CUDA

__global__ void plain(int* geneVec, float* probs, int* nComponents, float* randomNumbers,int *nGenes) 
{ 

    int xid = threadIdx.x + (blockDim.x * blockIdx.x); 

    float* currentProbs= (float*)malloc(sizeof(float)*tmp); 

     ..... 
     ..... 

    currentProbs[0] = probs[start]; 
    for (k=1;k<nComponents[0]; k++) 
    { 
     currentProbs[k] = currentProbs[k-1] + prob; 
    } 

     ... 
     ... 
     free(currentProbs); 

} 

Khi nó tĩnh (ngay cả các kích thước giống nhau) nó rất nhanh, nhưng khi CurrentProbs được cấp phát động (như trên) hiệu suất là khủng khiếp.

Câu hỏi này cho biết tôi có thể làm được điều này bên trong một hạt nhân: CUDA allocate memory in __device__ function

Dưới đây là một câu hỏi liên quan: Efficiency of Malloc function in CUDA

tôi đã tự hỏi nếu có phương pháp khác đã giải quyết này khác so với cái được đề xuất trong bài báo? Nó có vẻ vô lý mà người ta không thể malloc/miễn phí bên trong một hạt nhân mà không có loại hình phạt.

+0

'tmp' xuất phát từ đâu trong mã giả của bạn? – talonmies

+0

xin lỗi - tmp = nCác thành viên [0]; –

+0

Vì vậy, nó là liên tục cho mỗi lời gọi hạt nhân? Nếu vậy, tại sao bận tâm với phân bổ bộ nhớ dyanmic ở tất cả? – talonmies

Trả lời

7

Tôi nghĩ lý do giới thiệu malloc() làm chậm mã của bạn xuống là nó phân bổ bộ nhớ trong bộ nhớ toàn cục. Khi bạn sử dụng một mảng kích thước cố định, trình biên dịch có khả năng đặt nó trong tệp sổ đăng ký, nhanh hơn nhiều.

Việc phải làm một malloc bên trong hạt nhân của bạn có thể có nghĩa là bạn đang cố gắng làm quá nhiều công việc với một hạt nhân duy nhất. Nếu mỗi luồng phân bổ một lượng bộ nhớ khác nhau, thì mỗi luồng sẽ chạy một số lần khác nhau trong vòng lặp for và bạn nhận được rất nhiều phân kỳ dọc.

Nếu mỗi sợi trong một sợi dọc chạy vòng cùng một số lần, chỉ cần phân bổ lên phía trước. Ngay cả khi họ chạy một số lần khác nhau, bạn có thể sử dụng một kích thước không đổi. Nhưng thay vào đó, tôi nghĩ bạn nên xem xét cách bạn có thể cấu trúc lại mã của bạn để loại bỏ hoàn toàn vòng lặp đó khỏi hạt nhân của bạn.

+1

Trình biên dịch sẽ không bao giờ gán các biến nhân cho bộ nhớ chia sẻ trừ khi người lập trình định nghĩa chúng bằng cách sử dụng bộ định danh '__shared__'. Chỉ đăng ký hoặc bộ nhớ cục bộ. – talonmies

+0

@talonmies: Cảm ơn bạn đã làm rõ. Tôi đã chỉnh sửa câu trả lời. –

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