1

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

ジャワ:

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/MySamples# nvcc -ptx JCudaKernel.cu root@NVS295-CUDA:~/JCUDA/MySamples# ls -lrt | grep ptx -rw-r--r-- 1 ルート ルート 3295 3 月 27 日 17:46 JCudaKernel.ptx

2.) Java をビルドします: root@NVS295-CUDA:~/JCUDA/MySamples# javac -cp "../JCuda-All-0.5.0-bin-linux-x86/*:." JCudaTest.java

3.) 次のコードを実行します: root@NVS295-CUDA:~/JCUDA/MySamples# java -cp "../JCuda-All-0.5.0-bin-linux-x86/*:." JCudaTest 0 0 0 0 0

予想: 1 2 3 4 5

注: 問題がある場合は、x86 用に JCuda0.5.0 を使用しています。

私が間違っていることを教えてください。事前に感謝します:Ilir

4

1 に答える 1