Выделение большого закрепленного фрагмента памяти с использованием CUDA с Java

Я реализую вычисления GPU в программе, уже написанной на Java. Для этого я использую привязки jcuda. Мне нужен быстрый перенос памяти между устройствами, иногда относительно больших массивов. Если я хочу использовать потоки, я должен использовать закрепленную память. Проблема в том, что если я хочу выделить закрепленную на хосте память объемом более 600 МБ ОЗУ, я получаю исключение "CUDA_ERROR_OUT_OF_MEMORY". Вот код, который я использовал для проверки размера доступной закрепленной памяти:

    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);
    }

}

Теперь я знаю, что ОС может помешать мне использовать слишком много закрепленной памяти, так как она не является страничной. Дело в том, что у меня есть 48 ГБ (45 ГБ свободно) физической памяти, и мне нужен способ заставить ОС увеличить ее. Есть ли способ сделать это (элегантно, если это возможно)?

РЕДАКТИРОВАТЬ: ОС является 64-битной Windows 7 Professional SP1

2 ответа

Убедитесь, что вы используете Java в 64-битном режиме. В FAQ предлагается 32-битная версия по умолчанию, даже при 64-битной загрузке. В разделе часто задаваемых вопросов также рассказывается, как работать в 64-битном режиме, вам также нужно использовать 64-битные библиотеки DLL и т. Д.

@ ArchaeSoftware предлагает использовать cuMemHostRegister() / cuMemHostUnregister() закрепить меньшие участки памяти - разумная альтернатива.

Кажется, это старая страница, но без ответа. Полагаю, вы не используете свою оперативную память должным образом, так как по умолчанию Java сама по себе не выделяет много памяти для кучи. Вы можете заставить JVM использовать минимальную и максимальную память соответственно на -Xms и -Xmx, а при работе с 64-битной архитектурой используйте "-d64", чтобы после "-Xms" или "-Xmx"

Другие вопросы по тегам