Параллелизм C . Реализация цикла параллелизма в 2D-массиве

#c #arrays #parallel-processing #c 17

#c #массивы #параллельная обработка #c 17

Вопрос:

Хорошо, alphaBetaMiniMax является рекурсивным и зацикливается на 2d-плате. Здесь это небольшое упрощение, но любое улучшение времени выполнения — это большой выигрыш с точки зрения того, на сколько ходов вперед он может видеть.
Всего 2 дополнительных хода имеют реальное значение.

Проблема. Сам 2D-массив представляет собой шахматную доску и должен быть оптимизирован для параллельности. Мне известно о нескольких вариантах разделения внешнего цикла for, но внутренний цикл for сложен и, возможно, должен оставаться ванильным for .

 foo() {
  ....
  for (i=0; i<8; i  ) {
    for (j=calibrate(i); j<8; j=j 2) {
      // to account for checkerboard pattern, 
      // calibrate offsets board color where applicable
      makeMove(i,j)
      foo();
    }
  }
  

Это чрезмерное упрощение, и я (думаю, что я) структурировал и настроил код, чтобы избежать скачков данных и взаимоблокировок. Здесь это опущено.

Моя проблема в том, что делать с внешним циклом.

у for_each есть варианты параллельного выполнения, но я не знаю, будет ли это работать с внутренней частью, плюс мне нужно, чтобы каждый поток знал, в какой строке (что i) он находится, или кто знает, что происходит с каждой платой. У меня есть теории о том, как этого добиться, но это всего лишь так.

Мне просто нужен толчок в правильном направлении.

Комментарии:

1. Для нерегулярных шаблонов вы можете рассмотреть параллелизм задач. Это обеспечивается, например, Intel TBB и OpenMP. Если вы хотите придерживаться обычного C , вы можете просто решать каждую новую задачу в отдельном вызове std::async или std::thread .

2. Спасибо, большая проблема с потоками заключается в том, что каждый поток будет работать с другим объектом. Все эти объекты должны иметь частную переменную, сравниваемую в какой-то момент, чтобы определить, какой объект является «лучшим». Привязка потоков к циклу for (for_each, parallel_for и т.д.) Казалась лучшим способом сохранить его организованным и под контролем.

3. Я пошел с решением @DanielLangr и создал параллель для независимых потоков. Сейчас я пытаюсь продолжить оптимизацию, но этого было достаточно, чтобы меня настроили. К сожалению, я запустил плату 8×8 в 4-ядерной системе … что означает 9 потоков, включая этот вызывающий поток … на один больше, чем идеально. По-прежнему приводило к выигрышу в скорости выполнения, но задержка хода выявила проблему взаимоблокировки. Все еще работаю над хобби.

Ответ №1:

Эта библиотека только для заголовков может вам помочь. Он заботится об управлении потоками от вашего имени. Если каждая строка i не зависит от других строк, возможно, вы можете обернуть внутренний цикл как функцию, позволить библиотеке запускать его параллельно для каждой строки и собирать результаты, как показано в примерах в Github.