Несмотря на то, что во многих практических задачах, таких как умножение двух матриц, его дальнейшее разбиение, скорее всего, приведет к снижению производительности, поскольку это нарушит локальность памяти для потоков, если задачи, которые вы действительно выполняете, имеют низкую зависимость от данных, существует очевидное решение: вы просто перечисляете все триплеты (i,j,k)
от 0
до n^3-1
(при условии n = matrix.size()
), а затем разбиваете этот диапазон на 3 почти равных блока и передаете их каждому потоку. Тогда каждый поток может легко восстановить свою часть работы (задача # t
соответствует i+j*n+k*n^2
, поэтому:
i = t % n
j = (t/n) % n
k = t / n /n
Другое решение - использовать пул потоков и очередь для задач. Вы не назначаете каждому потоку всю работу в начале. Вы помещаете работу в очередь и позволяете каждому потоку получать от нее какой-то пакет работы. Когда пакет обрабатывается, возвращаетесь и извлекаете следующий пакет из очереди, а использование пакетов уменьшает конфликты параллелизма в очереди. Преимущество этого подхода состоит в том, что если время обработки данных зависит от конкретных данных, то вы будете балансировать фактическую работу, а не количество выполненных задач.