使用__syncthreads的常见每块指令

时间:2014-01-19 00:18:15

标签: cuda

我正在寻找一些关于Miller-Rabin素数证明的并行实现的建议。我们假设在输入时有一些大的奇数nm参数,这意味着它应向前搜索多少个奇数(所以它就像nn+2n+4等等。我想启动内核:

miller_rabin_kernel<<<m, k>>>(dev_n, ..)

其中k是另一个启动参数,例如它设置为20,但可能更大。对于每个线程,存在一些特定的数学计算,但是也存在对它们共同的指令(即“块宽”),并且这些必须在这些“线程范围”之前执行。据我所知,可以使用__syncthreads设置同步障碍,因此块中的每个线程都必须等到所有完成。我对这种结构的想法是:

__global__ void miller_rabin_kernel(..) {
    if (threadIdx.x == 0) {
        // Calculate t, s, that are common for all threads in current block
    }
    __syncthreads();

    // Perform further calculations with use of t and s
}

是否有更好的方法或是相当普遍的做法?

1 个答案:

答案 0 :(得分:1)

如果要计算的特定数量与每个块不同,那么您的示例是一种合理的方法。

如果您有大量的块,并且ts的计算相当紧张,那么您可以通过使用单独的内核预先计算{{1}来获得一些好处。 },t值,每个数量使用一个线程,但因此能够有效地使用块中的所有线程。由于所有线程都参与,因此该内核可以更有效地使用设备计算能力和内存带宽。然后,您可以将st数量保留在全局数组中,您可以按块访问这些数据:

s

在您的t = t_array[blockIdx.x]; t安装内核完成后,您可以按照您所示的方式调用主内核。

调用第一个内核会有一些开销,可能只有几微秒。同样,如果st的计算量很大,那么提高的效率可能会抵消可能带来的好处的开销。