小编Rob*_*lla的帖子

CUDA内核在CudaDeviceSynchronize之前没有启动

cuda profiler输出:

我在并发CUDA时遇到了一些麻烦.看一下附图.内核在标记点启动,时间为0.395秒.然后有一些绿色的CpuWork.最后,调用cudaDeviceSynchronize.在CpuWork之前启动的内核在同步调用之前没有启动.理想情况下,它应该与CPU工作并行运行.

void KdTreeGpu::traceRaysOnGpuAsync(int firstRayIndex, int numRays, int rank, int buffer)
{
    int per_block = 128;
    int num_blocks = numRays/per_block + (numRays%per_block==0?0:1);

    Ray* rays = &this->deviceRayPtr[firstRayIndex];
    int* outputHitPanelIds = &this->deviceHitPanelIdPtr[firstRayIndex];

    kdTreeTraversal<<<num_blocks, per_block, 0>>>(sceneBoundingBox, rays, deviceNodesPtr, deviceTrianglesListPtr, 
                                                firstRayIndex, numRays, rank, rootNodeIndex, 
                                                deviceTHitPtr, outputHitPanelIds, deviceReflectionPtr);

    CUDA_VALIDATE(cudaMemcpyAsync(resultHitDistances[buffer], deviceTHitPtr, numRays*sizeof(double), cudaMemcpyDeviceToHost));
    CUDA_VALIDATE(cudaMemcpyAsync(resultHitPanelIds[buffer], outputHitPanelIds, numRays*sizeof(int), cudaMemcpyDeviceToHost));
    CUDA_VALIDATE(cudaMemcpyAsync(resultReflections[buffer], deviceReflectionPtr, numRays*sizeof(Vector3), cudaMemcpyDeviceToHost));
}
Run Code Online (Sandbox Code Playgroud)

memcopies是异步的.结果缓冲区就像这样分配

unsigned int flag = cudaHostAllocPortable;

CUDA_VALIDATE(cudaHostAlloc(&resultHitPanelIds[0], MAX_RAYS_PER_ITERATION*sizeof(int), flag));
CUDA_VALIDATE(cudaHostAlloc(&resultHitPanelIds[1], MAX_RAYS_PER_ITERATION*sizeof(int), flag));
Run Code Online (Sandbox Code Playgroud)

希望找到解决方案.尝试了很多东西,包括没有在默认流中运行.当我添加cudaHostAlloc时,我发现异步方法返回到CPU.但是,如果内核在稍后调用deviceSynchronize之前未启动,那么这没有任何帮助.

resultHitDistances[2] 包含两个已分配的内存区域,以便当CPU读取0时,GPU应将结果置于1.

谢谢!

编辑:这是调用traceRaysAsync的代码.

int numIterations = ceil(float(this->numPrimaryRays) / MAX_RAYS_PER_ITERATION);
int numRaysPrevious …
Run Code Online (Sandbox Code Playgroud)

cuda

2
推荐指数
1
解决办法
1036
查看次数

CUFFT具有双精度

我在使用CUDA FFT库时遇到一些问题。

我将输入声明为cuDoubleComplex,但编译器返回以下错误:此类型与cufftComplex类型的参数不兼容。通过Internet搜索后,我发现文件cufft.h,其中有一行typedef cuComplex cufftComplex;。我的问题是,在cuComplex.h库中,很显然cuComplex具有单浮点精度(typedef cuFloatComplex cuComplex;),但是我想要双精度。

这可能吗?

特别是,我获得以下信息:

error: argument of type "cufftDoubleComplex *" is incompatible with parameter of type "cufftComplex *"
Run Code Online (Sandbox Code Playgroud)

在这一行:

cufftExecC2C(plan, data1, data2, CUFFT_FORWARD);
Run Code Online (Sandbox Code Playgroud)

cuda fft double-precision cufft

2
推荐指数
1
解决办法
2390
查看次数

我该如何阅读PTX?

我正在使用Capabilities 3.5,CUDA 5和VS 2010(显然是Windows).

我有兴趣阅读已编译的代码,以更好地理解我的C代码更改的含义.

  • 我需要在VS中使用什么配置来编译代码以便于阅读(将编译设置为足够的PTX?)?
  • 我需要使用什么工具对生成的PTX进行反向工程才能读取它?

cuda

2
推荐指数
1
解决办法
1428
查看次数

为什么我不能使用单个线程来初始化共享内存?

这似乎应该很简单,但我找不到任何参考,所以我在这里问.

我有以下CUDA内核,我将在2-D线程块的网格中启动:

__global__ void kernel(){

    if (threadIdx.x == 0 && threadIdx.y == 0) {
        __shared__ int test = 100;
    }
    __syncthreads();

    // Do more stuff
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译时,我收到错误"初始化程序不允许共享变量"

我究竟做错了什么?在我看来,我只有一个线程正在进行初始化...

谢谢!

cuda gpu shared-memory

2
推荐指数
1
解决办法
942
查看次数

一个函数在CUDA C ++中调用另一个函数

我对CUDA编程有问题!输入是矩阵A(2 x 2),输出是矩阵A(2 x 2),每个新值都是**旧值的3指数**示例:输入:A:{2,2}输出:A { 8,8} {2,2} {8,8}

我在CudaCode.CU文件中有2个功能:

   __global__ void Power_of_02(int &a)
{
    a=a*a;
}

 //***************
__global__ void Power_of_03(int &a)
{
    int tempt = a;
    Power_of_02(a); //a=a^2;
    a= a*tempt; // a = a^3
}
Run Code Online (Sandbox Code Playgroud)

和内核:

__global__ void CudaProcessingKernel(int *dataA )    //kernel function  

   {  
        int bx = blockIdx.x;  
    int tx = threadIdx.x;  
        int tid = bx * XTHREADS + tx;  

    if(tid < 16)
    {
    Power_of_03(dataA[tid]);
        }
    __syncthreads();

   }  
Run Code Online (Sandbox Code Playgroud)

我认为是正确的,但是会出现错误:仅在compute_35或更高版本的体系结构上允许从__global__函数(“ Power_of_03”)调用__global__函数(“ Power_of_02”)

为什么我错了?怎么修呢?

parallel-processing cuda global function call

2
推荐指数
1
解决办法
2730
查看次数

推力矢量距离计算

考虑以下数据集和质心。有 7 个个体和两个均值,每个均具有 8 个维度。它们存储在行主序中。

short dim = 8;
float centroids[] = {
    0.223, 0.002, 0.223, 0.412, 0.334, 0.532, 0.244, 0.612, 
    0.742, 0.812, 0.817, 0.353, 0.325, 0.452, 0.837, 0.441
};   
float data[] = {
    0.314, 0.504, 0.030, 0.215, 0.647, 0.045, 0.443, 0.325,
    0.731, 0.354, 0.696, 0.604, 0.954, 0.673, 0.625, 0.744, 
    0.615, 0.936, 0.045, 0.779, 0.169, 0.589, 0.303, 0.869, 
    0.275, 0.406, 0.003, 0.763, 0.471, 0.748, 0.230, 0.769, 
    0.903, 0.489, 0.135, 0.599, 0.094, 0.088, 0.272, 0.719, 
    0.112, 0.448, 0.809, 0.157, 0.227, 0.978, …
Run Code Online (Sandbox Code Playgroud)

c++ thrust

2
推荐指数
1
解决办法
970
查看次数

opencl中共享内存vs纹理内存

我正在Opencl中编写去隔行代码.我正在使用本地内存中的read_imageui()API读取像素.

就像下面的代码一样:https: //opencl-book-sa​​mples.googlecode.com/svn-history/r29/trunk/src/Chapter_19/oclFlow/lkflow.cl

根据我的理解,当我们使用此API读取像素时,我们正在从纹理内存中读取.我怀疑在共享内存中首先使用像素将有助于我获得任何速度,因为纹理内存已经充当缓存并提供对数据的快速访问.

任何人都可以澄清我的怀疑吗?

image-processing opencl

2
推荐指数
1
解决办法
411
查看次数

如何计算正在启动的 CUDA 线程数?

我有一个 CUDA 卡,具有: Cuda 计算功能 (3.5) 如果我有一个诸如 <<<2000,512>>> 的调用,内核中发生的迭代次数是多少?我以为是(2000*512),但测试并不能证明这一点?我还想确认我计算变量的方式是正确的。

情况是,在内核中,我根据线程号递增传递的全局内存号:

  int thr = blockDim.x * blockIdx.x + threadIdx.x;
  worknumber = globalnumber + thr;
Run Code Online (Sandbox Code Playgroud)

因此,当我返回到 CPU 时,我想确切地知道有多少增量,以便我可以跟踪,这样当我调用内核 GPU 处理下一组数字时,我就不会重复或跳过数字。

编辑 :

__global__ void allin(uint64_t *lkey, const unsigned char *d_patfile)
{

    uint64_t kkey;
    int tmp;
    int thr = blockDim.x * blockIdx.x + threadIdx.x;
    kkey = *lkey + thr;

if (thr > tmp) {
    tmp = thr;
    printf("%u \n", thr);
    }
}
Run Code Online (Sandbox Code Playgroud)

cuda nvcc

2
推荐指数
1
解决办法
4333
查看次数

如何在cpp和cuda模块中使用cuda类头文件

我正在尝试在我的设备中创建Color对象.这是我所拥有的简化版本:

Color.hpp中:

class Color { 
public:
    Color(){}
    float r, g, b;
    // other functions
}
Run Code Online (Sandbox Code Playgroud)

test.cu中:

__global__ void runCuda(){
    Color c = Color();
}

int main() {
   runCuda<<<1,1>>>()
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个错误的说法

不允许从全局函数调用主机函数

所以这很好.我只需要在Color(){}函数前面添加__host__和__device__.

但后来我收到以下错误:

主机没有命名类型

所以根据我的理解,这种情况正在发生,因为我没有用nvcc编译它.问题是我正在使用CMake来构建我的项目.我不太清楚它是如何做到的,但它似乎是用c ++编译器和.cu用nvcc编译器编译.cpp文件.

但在我的设备中,我想创建Color对象.有没有办法在我的CMakefiles或我的代码中解决这个问题?或者我是否需要为所有现有课程创建cuda版本?

c++ cuda

2
推荐指数
1
解决办法
2297
查看次数

CUDA内核启动后,针对特定SM的线程块调度的行为是什么?

我的问题是在开始执行内核后,在CUDA(特别是开普勒或较新的nvidia体系结构)中调度线程块。

根据我对开普勒架构的理解(可能不正确),可以随时将单个SM调度的活动块的数量受到限制(如果我没记错的话,可以分配16个块)。同样,据我了解,一旦将块计划在特定的SM上运行,它们就无法移动。

我很好奇的是,在最初选择块并开始在设备上执行之后,块调度和执行行为(假设内核具有的线程块多于所有SM中的活动块)。

SM中当前运行的单个活动块完成后是否立即执行新块?还是仅在SM完成其所有当前活动块后才执行下一组块?还是仅在所有SM完成所有当前活动的块执行后才启动它们?

另外,我听说块调度已“固定”到单个SM。我假设仅在块变为活动状态后才将其固定为单个SM。是这样吗

cuda

1
推荐指数
1
解决办法
768
查看次数