首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JCuda钉扎内存示例

JCuda钉扎内存示例
EN

Stack Overflow用户
提问于 2013-03-27 22:56:22
回答 1查看 908关注 0票数 1

JCuda + GEForce Gt640问题:

在GPU计算结果之后,我试图减少将内存从设备复制到主机的延迟。执行简单的Vector程序时,我发现大部分延迟实际上是将结果缓冲区复制回主机端。当将结果复制回20 is时,源缓冲区到设备侧的传输延迟是可忽略的~.30 is。

我做了这项研究,发现复制结果的一个更好的替代方法是使用固定内存。据我了解,这个内存是在主机端分配的,但是内核可以通过pci-e直接访问它,从而获得比批量计算后复制结果更快的速度。我使用了下面的示例,但是结果并没有得到我所期望的结果。

内核:{说明点的简单示例,只启动1块1线程}

代码语言:javascript
复制
extern "C"
__global__ void add(int* test)
{
    test[0]=1; test[1]=2; test[2]=3; test[3]=4; test[4]=5;
}

爪哇:

代码语言:javascript
复制
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 @ nvcc 295-CUDA:~/JCUDA/MySamples#nvcc -ptx JCudaKernel.cu root @nvcc 295-CUDA:~/JCUDA/MySamples# ls -lrt -lrt ptx -rw-r-1根根3295 / 17:46 JCudaKernel.ptx

2.)构建Java: root@x86 295-CUDA:~/JCuda/MySamples# javac -cp“./JCuda-所有-0.5.0-bin-linux-x86/*:”。JCudaTest.java

3.)运行代码:root@bin 295-CUDA:~/JCuda/MySamples# java -cp“./JCuda 0.5.0-bin-linux-x86/*:”。JCudaTest 0 0 0

预期:1 2 3 4 5

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

请事先告诉我我做错了什么,谢谢: Ilir

EN

回答 1

Stack Overflow用户

发布于 2014-04-23 21:05:42

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

诚然,文档在这里听起来有些误导:

cuMemAllocHost 分配字节大小的主机内存,这些内存是页面锁定的,设备可以访问.

这听起来像是一个明确的声明。但是,在这里“可访问”--而不是--意味着内存在所有情况下都可以直接用作内核参数。这只有在支持统一寻址的设备上才有可能。对于所有其他设备,必须使用cuMemHostGetDevicePointer获取与分配的主机指针相对应的设备指针。

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

编辑:

请注意,CUDA 6的新统一存储器功能实际上支持您最初打算做的事情:使用cudaMallocManaged,您可以分配主机和设备可以直接访问的内存(例如,它可以传递给内核,由设备编写,然后由主机读取)。不幸的是,这个概念不能很好地映射到Java,因为内存仍然是由CUDA管理的,而且这个内存不能替代内存,例如Java用于float[]数组的内存。但是,至少应该可以从与ByteBuffer一起分配的内存中创建一个cudaMallocManaged,以便您可以以FloatBuffer的形式访问这个内存。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15671126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档