【问题标题】:Allocation of large pinned memory chunk using CUDA with Java使用 CUDA 和 Java 分配大型固定内存块
【发布时间】:2013-02-22 18:05:51
【问题描述】:

我正在用 Java 编写的程序中实现 GPU 计算。为此,我使用jcuda 绑定。 我需要一个快速的主机到设备的内存传输,有时是相对较大的数组。如果我想使用流,我必须使用固定内存。问题是如果我想分配大于 cca 600 Mbs RAM 的主机固定内存,我会得到“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);
    }

}

现在,我知道操作系统会阻止我使用过多的固定内存,因为它是不可分页的。问题是我有 48Gb(45Gb 空闲)的物理内存,我需要一种强制操作系统给我更多的方法。有没有办法做到这一点(如果可能的话,优雅地)?

编辑:操作系统是 64 位 Windows 7 Professional SP1

【问题讨论】:

  • 您确定您使用的是主内存而不是设备上的内存吗?
  • 好吧,cuMemAllocHost() 函数是用来分配主机内存的,例如我给出的我不接触设备内存。至于操作系统,我目前使用的是 64 位 Windows 7 Professional SP1
  • 我建议您通过其他方式分配内存(例如,围绕 VirtualAlloc() 的薄包装),然后使用 cuMemHostRegister()/cuMemHostUnregister() 使其可用于 CUDA。
  • @Tom 是的,我使用的是 Java 6u35 windows x64。
  • NVIDIA 驱动程序中有一个已知错误,如果它不能使用低于 2 GB 左右的内存地址,它就会失败,因此请尝试使用 java -Xmx1G 之类的东西将 Java 的堆限制为 1 GB。

标签: java memory-management cuda jcuda


【解决方案1】:

检查您是否在 64 位模式下运行 Java。 FAQ 建议使用 default is 32-bit,即使是 64 位下载。链接的常见问题解答还告诉您如何在 64 位模式下运行,您还需要使用 64 位 DLL 等。

@ArchaeSoftware 建议使用cuMemHostRegister()/cuMemHostUnregister() 固定内存的较小部分是一个明智的选择。

【讨论】:

    【解决方案2】:

    这似乎是一个旧页面,但没有答案.. 我猜你没有正确利用你的 RAM,因为默认情况下 Java 本身不会为堆分配太多内存。您可以分别通过 -Xms 和 -Xmx 强制 JVM 使用最小和最大内存,并且当您使用 64 位架构时,在“-Xms”或“-Xmx”之后使用“-d64”

    【讨论】:

      猜你喜欢
      • 2012-11-30
      • 2013-10-06
      • 1970-01-01
      • 2013-10-16
      • 2021-01-11
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多