JCuda固定内存的例子

  • 本文关键字:内存 JCuda cuda jcuda
  • 更新时间 :
  • 英文 :


JCuda + GEForce Gt640问题:

我正试图减少与从设备复制内存到主机的延迟相关的结果已由GPU计算。在执行简单的Vector Add程序时,我发现大部分延迟确实是将结果缓冲区复制回主机端。源缓冲区到设备端的传输延迟可以忽略不计~。30毫秒,而将结果复制回来大约是20毫秒。

我做了研究,发现复制结果的一个更好的选择是使用固定内存。据我所知,这个内存是在主机端分配的,但是内核可以通过pci-e直接访问它,从而产生比在批量计算后复制结果更高的速度。我正在使用下面的例子,但结果并没有产生我所期望的。

内核:{简单的例子来说明这一点,启动1块1线程}

extern "C"
__global__ void add(int* test)
{
    test[0]=1; test[1]=2; test[2]=3; test[3]=4; test[4]=5;
}
Java:

import java.io.*;
import jcuda.*;
import jcuda.runtime.*;
import jcuda.driver.*;
import static jcuda.runtime.cudaMemcpyKind.*;
import static jcuda.driver.JCudaDriver.*;
public class JCudaTest
{
    public static void main(String args[])
    {
        // Initialize the driver and create a context for the first device.
        cuInit(0);
        CUdevice device = new CUdevice();
        cuDeviceGet(device, 0);
        CUcontext context = new CUcontext();
        cuCtxCreate(context, 0, device);
        // Load the ptx file.
        CUmodule module = new CUmodule();
        JCudaDriver.cuModuleLoad(module, "JCudaKernel.ptx");
        // Obtain a function pointer to the kernel function.
        CUfunction function = new CUfunction();
        JCudaDriver.cuModuleGetFunction(function, module, "add");
        Pointer P = new Pointer();
        JCudaDriver.cuMemAllocHost(P, 5*Sizeof.INT);
        Pointer kernelParameters = Pointer.to(P);
        // Call the kernel function with 1 block, 1 thread:
        JCudaDriver.cuLaunchKernel(function, 1, 1, 1, 1, 1, 1, 0, null, kernelParameters, null);
        int [] T = new int[5];
        JCuda.cudaMemcpy(Pointer.to(T), P, 5*Sizeof.INT, cudaMemcpyHostToHost);
         // Print the results:
         for(int i=0; i<5; i++)
                System.out.println(T[i]);
    }
}

1)。构建内核:root@NVS295-CUDA:~/JCUDA/myssamples # nvcc -ptx jcudakkernel .curoot@NVS295-CUDA:~/JCUDA/myssamples # ls -lrt | grep ptx-rw-r——r——1 root root 3295 Mar 27 17:46 jcudakkernel .ptx

2)。构建Java:root@NVS295-CUDA:~/JCUDA/myssamples # javac -cp "../JCUDA - all -0.5.0-bin-linux-x86/*:."JCudaTest.java

3)。运行代码:root@NVS295-CUDA:~/JCUDA/myssamples # java -cp "../JCUDA - all -0.5.0-bin-linux-x86/*:."JCudaTest00000

期待:123.45

注意:我使用JCuda0.5.0 x86如果这很重要。

请让我知道我做错了什么,并提前感谢:梅

这里的问题是设备可能直接访问主机内存。

无可否认,这里的文档听起来有些误导:

cuMemAllocHost

分配字节大小的主机内存,该内存是页锁定的,设备可以访问…

这听起来很清楚。然而,"accessible"这里不是表示内存可以在所有情况下直接用作内核参数。这只能在支持统一寻址的设备上实现。对于所有其他设备,需要使用cuMemHostGetDevicePointer获取与分配的主机指针对应的设备指针。

锁页主机内存的关键在于主机与设备之间的数据传输速度更快。在JCudaBandwidthTest示例中可以看到如何在JCuda中使用此内存(这是针对运行时API的,但对于驱动程序API,它的工作方式类似)。

编辑:

请注意,CUDA 6的新统一内存特性实际上支持您最初打算做的事情:使用cudaMallocManaged,您可以分配主机设备可直接访问的内存(从某种意义上说,例如,它可以传递给内核,由设备写入,然后由主机读取,而无需额外的努力)。不幸的是,这个概念不能很好地映射到Java,因为内存仍然是由CUDA管理的-并且这些内存不能取代内存,例如,Java VM用于float[]数组或左右。但是,至少应该可以从分配给cudaMallocManaged的内存中创建ByteBuffer,以便您可以访问该内存,例如,作为FloatBuffer

相关内容

  • 没有找到相关文章

最新更新