【发布时间】:2009-02-19 09:52:02
【问题描述】:
我最近编写了一个小型数字运算程序,它基本上在 N 维网格上循环并在每个点执行一些计算。
for (int i1 = 0; i1 < N; i1++)
for (int i2 = 0; i2 < N; i2++)
for (int i3 = 0; i3 < N; i3++)
for (int i4 = 0; i4 < N; i4++)
histogram[bin_index(i1, i2, i3, i4)] += 1; // see bottom of question
它运行良好,yadda yadda yadda,生成了可爱的图表 ;-) 但后来我想,我的计算机上有 2 个内核,为什么不让这个程序多线程,这样我可以将它的运行速度提高一倍?
现在,我的循环总共运行了大约 10 亿次计算,我需要一些方法在线程之间拆分它们。我想我应该将计算分组为“任务” - 说最外层循环的每次迭代都是一个任务 - 并将任务分发给线程。我考虑过
- 只给线程#n 最外层循环的所有迭代,其中
i1 % nthreads == n- 基本上预先确定了哪些任务转到哪些线程 - 试图设置一些受互斥保护的变量,该变量保存下一个需要执行的任务的参数(在本例中为
i1) - 动态地将任务分配给线程
有什么理由选择一种方法而不是另一种方法?还是我没有想到的另一种方法?这还重要吗?
顺便说一句,我用 C 编写了这个特定的程序,但我想我会在其他语言中再次做同样的事情,所以答案不必是特定于 C 的。 (不过,如果有人知道用于 Linux 的 C 库可以做这种事情,我很想知道)
编辑:在这种情况下,bin_index 是一个确定性函数,除了它自己的局部变量外,它不会改变任何东西。像这样的:
int bin_index(int i1, int i2, int i3, int i4) {
// w, d, h are constant floats
float x1 = i1 * w / N, x2 = i2 * w / N, y1 = i3 * d / N, y2 = i4 * d / N;
float l = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + h * h);
float th = acos(h / l);
// th_max is a constant float (previously computed as a function of w, d, h)
return (int)(th / th_max);
}
(虽然我很欣赏所有的 cmets,即使是那些不适用于确定性 bin_index 的 cmets)
【问题讨论】:
-
您能否更明确地说明您操作的数据?数据依赖性在并行编程中更为重要。开发 bin_index 中的内容
-
我添加了一些关于我正在尝试编写的具体示例的更多细节,希望对您有所帮助...
标签: multithreading loops