2012-09-12 52 views
0

我正在用Java編寫的程序中實現GPU計算。爲此,我使用了jcuda綁定。 我需要一個快速的主機到設備的內存傳輸,有時是相對較大的陣列。如果我想使用流,我必須使用固定內存。問題是如果我想分配大於cca 600 Mbs的RAM的主機固定內存,我會得到「CUDA_ERROR_OUT_OF_MEMORY」異常。 這是我用來測試可用的固定內存的大小不同的代碼:使用CUDA和Java分配大型固定內存塊

public static void main(String[] args) { 
    //Init GPU 
    JCudaDriver.setExceptionsEnabled(true); 

    // Initialize the device and create device context 
    cuInit(0); 
    CUdevice device = new CUdevice(); 
    cuDeviceGet(device, 0); 
    CUcontext context = new CUcontext(); 
    cuCtxCreate(context, 0, device); 

    Pointer p = new Pointer(); 

    int Kb = 1024; 
    int Mb = 1024 * Kb; 
    int Gb = 1024 * Mb; 
    int sequenceSize = 172*Mb; // times 4 for float 
    float[] expecteds = new float[sequenceSize]; 
    float[] actuals = new float[sequenceSize]; 
    Arrays.fill(expecteds, 3.33f); 
    int i = 0; 
    try { 
     JCudaDriver.cuMemAllocHost(p, sequenceSize* Sizeof.FLOAT); 
     FloatBuffer fb = p.getByteBuffer(0, sequenceSize* Sizeof.FLOAT). 
       order(ByteOrder.nativeOrder()). 
       asFloatBuffer(); 

     fb.position(0); 
     fb.put(expecteds); 
     fb.position(0); 
     fb.get(actuals); 
     JCudaDriver.cuMemFreeHost(p); 

    } catch (Exception e) { 
     e.printStackTrace(); 
     JCudaDriver.cuMemFreeHost(p); 
    } 

} 

現在,我知道,操作系統可以阻止我用太多的固定內存,因爲它是不可分頁。問題是我有48Gb(45Gb自由)的物理內存,我需要一種強制操作系統給我更多的方法。有沒有辦法做到這一點(如果可能,優雅)?

編輯:操作系統是64位Windows 7專業版SP1

+0

您確定您正在使用主存儲器而不是設備上的存儲器? –

+0

問題的操作系統是什麼? – talonmies

+0

好了,[cuMemAllocHost()](http://developer.download.nvidia.com/compute/cuda/4_2/rel/toolkit/docs/online/group__CUDA__MEM_gdd8311286d2c2691605362c689bc64e0.html)函數用來分配主機內存,並且在例子中我給了我不要觸摸設備的內存。至於操作系統,我目前使用64位Windows 7 Professional SP1 –

回答

1

檢查您是否在64位模式下運行Java。 FAQ建議default is 32-bit,即使是64位下載。鏈接的FAQ也告訴你如何以64位模式運行,你也需要使用64位的DLL等。

@ ArchaeSoftware建議使用cuMemHostRegister()/cuMemHostUnregister()來固定內存的較小部分是一個明智的選擇。

0

這似乎是一箇舊頁面,但沒有答案。 我猜你沒有正確地利用你的RAM,因爲默認情況下Java本身並沒有爲堆分配太多的內存。您可以強制JVM分別使用-Xms和-Xmx的最小和最大內存,當您在使用64位架構時,在「-Xms」或「-Xmx」之後使用「-d64」