2013-10-22 48 views
3

我試圖直接從Linux中的另一個PCIe設備訪問NIC中的DMA地址。具體來說,我試圖從NVIDIA GPU讀取這些數據,以便一起繞過CPU。我已經研究了零拷貝網絡和DMA到用戶空間的帖子,但他們要麼沒有回答這個問題,要麼涉及到從內核空間到用戶空間的一些副本。我試圖避免使用任何CPU時鐘,因爲與延遲不一致,並且我對延遲要求非常嚴格。DMA over PCIe到其他設備

我拿到了我使用的intel卡(e1000e驅動程序)的NIC驅動程序,並且我找到了環形緩衝區的分配位置。正如我從之前的一篇文章中所理解的那樣,我會對dma_addr_t類型的描述符感興趣。他們也有一個名爲dma的rx_ring結構體的成員。我使用ioctl調用通過了desc和dma成員,但除了零之外,我無法在GPU中獲取任何內容。

GPU的代碼如下:

int *setup_gpu_dma(u64 addr)              
{                     
    // Allocate GPU memory              
    int *gpu_ptr;                 
    cudaMalloc((void **) &gpu_ptr, MEM_SIZE);          

    // Allocate memory in user space to read the stuff back      
    int *h_data;                 
    cudaMallocHost((void **)&h_data, MEM_SIZE);         

    // Present FPGA memory to CUDA as CPU locked pages       
    int error = cudaHostRegister((void **) &addr, MEM_SIZE,      
     CU_MEMHOSTALLOC_DEVICEMAP);            
    cout << "Allocation error = " << error << endl;        

    // DMA from GPU memory to FPGA memory           
    cudaMemcpy((void **) &gpu_ptr, (void **)&addr, MEM_SIZE, cudaMemcpyHostToDevice); 
    cudaMemcpy((void **) &h_data, (void **)&gpu_ptr, MEM_SIZE, cudaMemcpyDeviceToHost); 

    // Print the data                

    // Clean up 
}       

我在做什麼錯?

+0

評論中它說「FPGA」,它應該說「NIC緩衝區」? –

+0

是的,它應該。我從另一個例子中複製了部分代碼,在Windows中做了非常類似的事情。他們從FPGA PCI-e板讀取數據。對於那個很抱歉。 – jrk0414

+0

您有沒有機會看NVIDIA的GPUDirect文檔:http://docs.nvidia.com/cuda/gpudirect-rdma/index.html – njuffa

回答

1

cudaHostRegister()在已分配的主機內存上運行,所以您必須通過addr而不是&addr。如果addr不是主機指針,這將不起作用。如果它一個主機指針,你的功能接口應該使用void *然後就不需要該類型轉換。

+0

使用你的建議,我用(void *)addr代替(void **)&addr。儘管我仍然只有零。如果我沒有將它轉換爲void *,我會得到一個錯誤,指出void與u64(這是一個無符號long long)不兼容。 – jrk0414

+0

確保您傳遞給'cudaHostRegister()'的地址是有效的主機內存地址。另外,是的,你不能直接將'u64'轉換爲'void *',你必須在中間粘貼一箇中間轉換爲'uintptr_t'。 'u64 u =(u64)(uintptr)t)p;''void * p =(void *)(uintptr_t)u;'' – ArchaeaSoftware