我正在寻找一些关于Miller-Rabin素数证明的并行实现的建议。我们假设在输入时有一些大的奇数n
和m
参数,这意味着它应向前搜索多少个奇数(所以它就像n
,n+2
, n+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
}
是否有更好的方法或是相当普遍的做法?
答案 0 :(得分:1)
如果要计算的特定数量与每个块不同,那么您的示例是一种合理的方法。
如果您有大量的块,并且t
和s
的计算相当紧张,那么您可以通过使用单独的内核预先计算{{1}来获得一些好处。 },t
值,每个数量使用一个线程,但因此能够有效地使用块中的所有线程。由于所有线程都参与,因此该内核可以更有效地使用设备计算能力和内存带宽。然后,您可以将s
和t
数量保留在全局数组中,您可以按块访问这些数据:
s
在您的t = t_array[blockIdx.x];
,t
安装内核完成后,您可以按照您所示的方式调用主内核。
调用第一个内核会有一些开销,可能只有几微秒。同样,如果s
和t
的计算量很大,那么提高的效率可能会抵消可能带来的好处的开销。