Предположим, я хочу использовать многопоточность для умножения матрицы i × j на матрицу j × k, чтобы получить матрицу i × k, где i, j и k неизвестны. Число потоков n, которым поручено выполнение умножения матриц, также неизвестно. Как я могу эффективно определить индексы матрицы продуктов, за вычисление которых отвечает каждый поток?
Для справки, мой первоначальный подход заключался в том, чтобы разделить общее количество элементов (произведение i и k) на количество потоков (n), чтобы получить количество индексов, за которые отвечает каждый поток. При создании каждого потока он передавал свой номер (т. Е. Поток 0, 1, 2 ...) методу умножения, чтобы определить начальный и конечный индексы, как если бы матрица была одномерной (то есть [0] [0] = 0, [0] [1] = 1, [0] [2] = 2 ...). Наконец, метод будет перебирать каждый одномерный индекс, преобразовывать его в его двумерный аналог и определять значение для каждого индекса.
Этот подход работает, но я заметил, что в Java он не ускоряет умножение матриц. Фактически, часто кажется, что это замедляет процесс по мере увеличения размера матриц. Если предположить, что я правильно реализовал потоки в Java, почему это может быть? Я подозреваю, что это связано с вычислениями, необходимыми для определения двумерных индексов (в моем случае, две дополнительные арифметические операции на каждый индекс), но я также знаю, что существует некоторый уровень накладных расходов, связанных с реализацией потоков.
Вот моя реализация на случай, если приведенное выше описание не было ясным:
public synchronized void perform(int id) {
int first = id * NUM_OPS;
int last = first + NUM_OPS - 1;
if (id == NUM_THREADS - 1)
last += (i * k) % NUM_THREADS;
if (last >= i * k)
return;
for(int curr = first; curr <= last; curr++) {
int p = curr / k;
int r = curr % k;
for(int q = 0; q < j; q++)
C[p][r] += A[p][q] * B[q][r];
}
}
@Andreas В итоге все получилось очень хорошо, спасибо! Однако я все еще не уверен, почему мой первоначальный подход был медленным. Возможно, моя реализация на самом деле не была параллельной.




Вы сказали «эффективно», верно? Тогда «Как создавалась каждая ветка» противоречит вашим целям, потому что запуск потоков выполняется медленно. Вы должны использовать пул потоков.