Memory CUDA内核和内存访问(一个内核不能完全执行,下一个内核不能启动)

Memory CUDA内核和内存访问(一个内核不能完全执行,下一个内核不能启动),memory,cuda,Memory,Cuda,我这里有麻烦。我启动两个内核,检查某个值是否是预期值(memcpy到主机),如果是,我停止,如果不是,我再次启动两个内核 第一个内核: __global__ void aco_step(const KPDeviceData* data) { int obj = threadIdx.x; int ant = blockIdx.x; int id = threadIdx.x + blockIdx.x * blockDim.x; *(data->added) = 1; while(*(da

我这里有麻烦。我启动两个内核,检查某个值是否是预期值(memcpy到主机),如果是,我停止,如果不是,我再次启动两个内核

第一个内核:

__global__  void aco_step(const KPDeviceData* data)
{
int obj = threadIdx.x;
int ant = blockIdx.x;
int id = threadIdx.x + blockIdx.x * blockDim.x;

*(data->added) = 1;

while(*(data->added) == 1)
{
    *(data->added) = 0;

    //check if obj fits
    int fits = (data->obj_weights[obj] + data->weight[ant] <= data->max_weight);
    fits = fits * !(getElement(data->selections, data->selections_pitch, ant, obj));

    if(obj == 0)
        printf("ant %d going..\n", ant);
    __syncthreads();

...
obj_权重数组的大小正确,n*sizeof(int)。权重数组ants*sizeof(float)也是如此。所以他们不是出界的

这个之后的内核在开头有一个printf,它也没有被打印出来,在printf之后它在设备内存上设置了一个变量,这个内存在内核完成后被复制到CPU,当我在CPU代码中打印它时,它不是正确的值。所以我认为这个内核做了一些非法的事情,而第二个内核甚至没有被启动

我正在测试一些实例,当我启动8个块和512个线程时,它运行正常。32个块,512个线程,好的。但是8个块和1024个线程,这种情况下,内核不工作,32个块和1024个线程也不工作

我做错什么了吗?内存访问?我启动的线程太多了吗

编辑:尝试删除“添加的”变量和while循环,因此它应该只执行一次。仍然不起作用,没有打印任何内容,即使printf正好在三个初始行之后,并且下一个内核也没有打印任何内容

编辑:另一件事,我使用的是GTX 570,因此“每个块的最大线程数”是1024个。也许我会坚持使用512最大值,或者检查我可以将该值设置得多高。

\u syncthreads()
只有当条件在一个块的所有线程上的计算结果相同时,才允许使用条件代码内部

在您的例子中,该条件受到竞争条件的影响,并且是不确定的,因此它很可能针对不同的线程计算出不同的结果


printf()
输出仅在内核成功完成后显示。在这种情况下,这不是由于上述问题,因此输出永远不会显示。您可以通过测试所有CUDA函数调用的返回码来解决这个问题。

好的,我得到了syncthreads点,完全忘记了它。但是关于内存写入,如果多个线程向同一地址写入相同的值,该值将被更新,未知的是它将被更新多少次。摘自这里:由于我不知道内核启动会返回错误,所以我很快就会发现问题。在这里捕获错误代码:我不完全确定*(data->added)测试要做什么。但至少要删除争用条件,请在while()之前插入一个_syncthreads()。由于_syncthreads()会对每个块进行同步,因此还需要将标志移回共享内存(不要害怕,如果编程正确,共享内存没有问题)。我使用的是随机分配的共享数组,它们所做的只是对我的代码进行bug。我将添加的变量移回shared,它现在可以工作了。我还对代码做了一些修改。每个块启动512个线程没问题,但显然启动1024个线程没有问题,即使我的GPU支持每个块1024个线程。缺少一些其他资源(即寄存器或共享内存)可能会阻止您启动每个块支持的最大线程数。您可以使用Nvidia的入住率计算器电子表格来检查您的具体案例的限额。
int* el = (int*) ((char*)mat + row * pitch) + col;
return *el;