Недавно я написал небольшую программу обработки чисел, которая в основном переходит по 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
Это работало нормально, Ядда Ядда Ядда, получились прекрасные графики ;-) Но потом я подумал, у меня на компьютере 2 ядра, почему бы не сделать эту программу многопоточной, чтобы я мог запустить ее вдвое быстрее?
Теперь, мои циклы, скажем, около миллиарда вычислений, и мне нужно как-то разделить их между потоками. Я полагаю, что должен сгруппировать вычисления в «задачи» - скажем, каждая итерация самого внешнего цикла - задача - и передать задачи потокам. Я рассмотрел
- просто дает потоку #n все итерации самого внешнего цикла, где
i1 % nthreads == n
- по существу, предопределяя, какие задачи и в какие потоки идут
- пытается установить некоторую переменную, защищенную мьютексом, которая содержит параметр (ы) (в данном случае
i1
) следующей задачи, которая должна быть выполнена - динамическое назначение задач потокам
Какие есть причины выбирать один подход перед другим? Или другой подход, о котором я не думал? Это вообще имеет значение?
Кстати, я написал эту конкретную программу на C, но я думаю, что я буду делать то же самое снова и на других языках, поэтому ответы не должны быть специфичными для C. (Если кто-нибудь знает библиотеку C для Linux, которая делает подобные вещи, я бы хотел узнать об этом)
EDIT : в этом случае 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);
}
(хотя я ценю все комментарии, даже те, которые не относятся к детерминированному bin_index)