Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cuda “什么可能导致?”;“未定义的行为”;在这个并行GPU代码中?_Cuda_Undefined Behavior - Fatal编程技术网

Cuda “什么可能导致?”;“未定义的行为”;在这个并行GPU代码中?

Cuda “什么可能导致?”;“未定义的行为”;在这个并行GPU代码中?,cuda,undefined-behavior,Cuda,Undefined Behavior,假设core1和core2尝试将变量a和b写入同一内存位置 这里如何解释UB 我们不知道a或b是否写入该内存位置(作为最后一个操作) 我们甚至不知道那里写的是什么(垃圾) 甚至目标内存地址也可能计算错误(segfault?) 一些逻辑门产生错误的电流,CPU会自行禁用 CPU的频率信息变得损坏,并高度超频(并自行中断) 我可以假设只有第一个选项对所有CPU(和GPU)供应商有效吗 我刚刚将下面的代码转换成并行GPU代码,它似乎工作正常 通用代码: for (j=0; j<YRES/CE

假设core1和core2尝试将变量a和b写入同一内存位置

这里如何解释UB

  • 我们不知道a或b是否写入该内存位置(作为最后一个操作)
  • 我们甚至不知道那里写的是什么(垃圾)
  • 甚至目标内存地址也可能计算错误(segfault?)
  • 一些逻辑门产生错误的电流,CPU会自行禁用
  • CPU的频率信息变得损坏,并高度超频(并自行中断)
我可以假设只有第一个选项对所有CPU(和GPU)供应商有效吗

我刚刚将下面的代码转换成并行GPU代码,它似乎工作正常

通用代码:

for (j=0; j<YRES/CELL; j++) // this is parallelized
        for (i=0; i<XRES/CELL; i++) // this is parallelized
        {
            r = fire_r[j][i];
            g = fire_g[j][i];
            b = fire_b[j][i];
            if (r || g || b)
                for (y=-CELL; y<2*CELL; y++)
                    for (x=-CELL; x<2*CELL; x++)
                        addpixel(i*CELL+x, j*CELL+y, r, g, b, fire_alpha[y+CELL][x+CELL]);
   //addpixel accesses neighbour cells' informations and writes on them
   //and makes UB
            r *= 8;
            g *= 8;
            b *= 8;
            for (y=-1; y<2; y++)
                for (x=-1; x<2; x++)
                    if ((x || y) && i+x>=0 && j+y>=0 && i+x<XRES/CELL && j+y<YRES/CELL)
                    {
                        r += fire_r[j+y][i+x];
                        g += fire_g[j+y][i+x];
                        b += fire_b[j+y][i+x];
                    }
            r /= 16;
            g /= 16;
            b /= 16;
            fire_r[j][i] = r>4 ? r-4 : 0; // UB
            fire_g[j][i] = g>4 ? g-4 : 0; // UB
            fire_b[j][i] = b>4 ? b-4 : 0;
        }

for(j=0;j对于上述代码,第一个选项是唯一可能的选项。基本上,如果您假设有足够的线程/处理器并行执行所有循环,则内部嵌套循环(x
和y循环)将具有不确定的值

例如,如果我们只考虑

r += fire_r[j+y][i+x];

截面,在
fire\r[j+y][i+x]处的值
可以是原始循环,也可以是同一循环的另一个实例在另一个线程中完成的结果。

对于上面的代码,第一个选项是唯一可能的选项。基本上,如果您假设有足够的线程/处理器并行执行所有循环,那么内部嵌套循环(x和y的值将不确定

例如,如果我们只考虑

r += fire_r[j+y][i+x];

第节中,
fire_r[j+y][i+x]
处的值可以是原始值,也可以是同一循环的另一个实例在另一个线程中完成的结果。

在xf86和xf86_64体系结构上,这意味着我们不知道a或b是否写入该内存位置(作为最后一个操作),因为加载/存储操作是32(对于这两个)或64位(仅xf86_64)内存对齐的数据类型是原子的

在其他架构上,通常我们甚至不知道那里写的是什么(垃圾)是一个有效的答案——当然在RISC架构上,我目前不知道GPU上写的是什么

请注意,代码工作的事实并不意味着它是正确的,在99%的情况下,它是诸如“存在编译器错误,代码在上一版本之前一直工作”或“代码在开发机器上工作。选择用于生产的服务器已损坏”之类的句子的来源:

编辑:


在NVidia GPU上,我们有弱有序的内存模型。在中没有明确说明存储操作是原子的。写入操作来自同一个线程,因此并不意味着加载/存储操作是原子的。

在xf86和xf86_64体系结构上,这意味着我们不知道a或b是否写入该内存位置(作为最后一个操作),因为32位(两者)或64位(仅限xf86_64)内存对齐的数据类型的加载/存储操作是原子的

在其他架构上,通常我们甚至不知道那里写的是什么(垃圾)是一个有效的答案——当然在RISC架构上,我目前不知道GPU上写的是什么

请注意,代码工作的事实并不意味着它是正确的,在99%的情况下,它是诸如“存在编译器错误,代码在上一版本之前一直工作”或“代码在开发机器上工作。选择用于生产的服务器已损坏”之类的句子的来源:

编辑:


在NVidia GPU上,我们有弱有序的内存模型。在中没有明确说明存储操作是原子的。写入操作来自同一个线程,因此这并不意味着加载/存储操作是原子的。

当我看到标题时,我直接想回答未定义的
行为
:p您的行为到底是什么问题?如何定义“未定义的行为”通常是定义的?或者这是专门针对某个GPU代码的?我需要了解它有多糟糕。我假设第一个选项,但不确定。根据定义,它有多糟糕没有定义。它可能不会杀死你的猫,但没有人保证,因为未定义的行为显然不被认为是你应该做的事情我一直在想。你不会杀死GPU,就像玩crysis:你只是在做合法的操作,顺序非常随意。当我看到标题时,我直接想回答未定义的行为。你的问题是什么?如何定义“未定义的行为”通常是定义的?或者这是专门针对某个GPU代码的?我需要了解它有多糟糕。我假设第一个选项,但不确定。根据定义,它有多糟糕没有定义。它可能不会杀死你的猫,但没有人保证,因为未定义的行为显然不被认为是你应该做的事情我一直在想。你不会杀死GPU,就像玩crysis一样:你只是在做合法的操作,顺序非常随机。“如果我启用优化,它就什么都做不了”“如果我启用优化,它就什么都做不了”