Вероятно, вы получите наилучшую производительность, если будете использовать один поток для каждого ядра ЦП, доступного для машины, на которой работает ваше приложение.Вы не получите никакого выигрыша в производительности, запустив больше потоков, чем у вас есть процессоры.
Если вы планируете порождать новые потоки каждый раз, когда выполняете умножение матриц, тогда очень мало надежды на то, что ваше многопоточное приложение когда-либо превзойдет однопоточную версию, если вы не умножаете действительно огромные матрицы.Издержки, связанные с созданием потока, слишком велики по сравнению со временем, необходимым для умножения матриц.Тем не менее, вы можете получить значительное повышение производительности, если будете запускать все рабочие потоки один раз при запуске процесса, а затем использовать их снова и снова, чтобы выполнить многократное умножение матриц.
Для каждой пары матриц, которые вы хотите умножить, вы захотите загрузить матрицы умножения и умножения в память один раз, а затем разрешить всем вашим рабочим потокам одновременно обращаться к памяти.Это должно быть безопасно, потому что эти матрицы не будут меняться во время умножения.
Вы также должны иметь возможность разрешить всем рабочим потокам одновременно записывать свои выходные данные в одну и ту же выходную матрицу, поскольку (из-за природы матрицыумножение) каждый поток заканчивает тем, что записывает свой вывод в различные элементы матрицы, и не будет никакого конфликта.
Я думаю, что вы должны распределить строки между потоками, поддерживая целое число NextRowToProcess
, которое совместно используетсявсе темы.Всякий раз, когда поток готов обработать другую строку, он вызывает InterlockedIncrement
(или любую атомарную операцию приращения, доступную на вашей платформе), чтобы безопасно получить следующую строку для обработки.