
我在并发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 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) 我正在使用Capabilities 3.5,CUDA 5和VS 2010(显然是Windows).
我有兴趣阅读已编译的代码,以更好地理解我的C代码更改的含义.
这似乎应该很简单,但我找不到任何参考,所以我在这里问.
我有以下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编程有问题!输入是矩阵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”)
为什么我错了?怎么修呢?
考虑以下数据集和质心。有 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) 我正在Opencl中编写去隔行代码.我正在使用本地内存中的read_imageui()API读取像素.
就像下面的代码一样:https: //opencl-book-samples.googlecode.com/svn-history/r29/trunk/src/Chapter_19/oclFlow/lkflow.cl
根据我的理解,当我们使用此API读取像素时,我们正在从纹理内存中读取.我怀疑在共享内存中首先使用像素将有助于我获得任何速度,因为纹理内存已经充当缓存并提供对数据的快速访问.
任何人都可以澄清我的怀疑吗?
我有一个 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) 我正在尝试在我的设备中创建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版本?
我的问题是在开始执行内核后,在CUDA(特别是开普勒或较新的nvidia体系结构)中调度线程块。
根据我对开普勒架构的理解(可能不正确),可以随时将单个SM调度的活动块的数量受到限制(如果我没记错的话,可以分配16个块)。同样,据我了解,一旦将块计划在特定的SM上运行,它们就无法移动。
我很好奇的是,在最初选择块并开始在设备上执行之后,块调度和执行行为(假设内核具有的线程块多于所有SM中的活动块)。
SM中当前运行的单个活动块完成后是否立即执行新块?还是仅在SM完成其所有当前活动块后才执行下一组块?还是仅在所有SM完成所有当前活动的块执行后才启动它们?
另外,我听说块调度已“固定”到单个SM。我假设仅在块变为活动状态后才将其固定为单个SM。是这样吗