【发布时间】:2013-05-19 10:58:32
【问题描述】:
我有这样一个 3D 内核,我目前在一个块上运行:
// The two following variables are set elsewhere in the program.
// I give them possible value here for demonstration purposes.
int* N = {14, 5, 1};
int L = 2; // N's size - 1
int idx = blockIdx.x * blockDim.x + threadIdx.x;
int idy = blockIdx.x * blockDim.y + threadIdx.y;
int idz = blockIdx.x * blockDim.z + threadIdx.z;
int idxInc = idx + 1; // for not to waste threads whose idx = 0
if (idxInc >= 1 && idxInc <= L)
{
if (idy < N[idxInc])
{
if (idz < N[idxInc-1])
{
dw[ idxInc ][ idy ][ idz ] = 0;
}
}
}
如果我在一个尺寸为 {2, 5, 14} 的块上启动这个内核,一切都很好。这正是块的每个维度所需的线程数,以便内核执行前两行中定义的数据工作。现在,我不知道如何在多个块之间划分这项工作。我的大脑错误只是试图在两个块上为每个维度找到合适数量的线程。 此外,L 可能会有所不同(但我可能会对此有所限制),更有可能 N[1] 会发生很大变化(在此示例中为 5,但可能是 128、256 或 2048...)。所以我必须找到一种算法,自动平衡块的数量,以及块的三个维度中每个维度的线程数。
我真的不知道该怎么办,现在我觉得自己很愚蠢! 我开始认为我应该停止玩 3 维......或者也许有一个我看不到的简单技巧......
一些帮助? 谢谢!
编辑:连续检查结果...
for (layer = 1; layer <= L; layer++)
{
for (i = 0; i < N[layer]; i++)
{
for (j = 0; j < N[layer-1]; j++)
{
printf("%1.0f", dw[ layer ][ i ][ j ]);
}
printf("\n");
}
printf("\n");
}
显示的每个数字都应该是 0。
【问题讨论】:
-
您是说问题的总范围是由 {2, 5, 14} 线程块结构定义的吗?如果是这样,那只是一个小问题。扩展它的方法是提出一个更大的数据集。在这种情况下,我见过的大多数代码只是选择一些方便的线程块大小,例如 {8, 8, 8} 并将整个 3D 域划分为该大小的块,每个线程在一个元素上运行。就像在一维情况下一样,我们应该在内核代码中进行线程检查,检查线程索引与有效数据索引。你会在域的边缘有一些浪费的线程;没关系。
-
这是我上面描述的complete code example。
-
int* N = {2, 5, 14} 只是我使用的一个示例,因为我发现更容易考虑小数据。如果你还记得的话,它仍然是我试图并行化的神经网络……中心值 5 是隐藏层的神经元数量。它可能设置为 128 或 1024。用户必须选择此值。但是层数 2 不太可能改变。并且输入层的神经元数量 14 永远不会改变。因此,如果我为这样一组数据选择一个对称块:{2, 1024, 14},可能会导致大量线程浪费...
-
无论如何,我的代码不起作用,即使对于对称块也是如此。如果我把 128 个神经元放在隐藏层 -> N = {14, 128, 1},并选择你方便的块 {8,8,8},我需要发射 16 个块。结果只是一个 0 的小方块,其大小为...8x8x8!其余的没有初始化。我想这与线程 ID 计算有关。我正在寻找,但我的大脑坏了……
-
这个 -> "if (idx==127 && idy == 127 && idz == 127) printf("HELLO\n");"没问题,打印出来了。但是这个->“if (idx==0 && idy == 127 && idz == 13) printf("BONJOUR\n");"由于某种原因,不显示!为什么有线程 {127,127,127} 而没有线程 {0, 127, 13} ???我疯了!
标签: cuda