Организация задач на основе научных расчетов - PullRequest
1 голос
/ 20 июля 2011

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

Ранее я кодировал это функционально, вызывая функции по мере необходимости и сохраняя все в оперативной памяти. Это был ужасный подход, но тогда меня больше волновала теория.

Я планирую переписать код на C ++ по разным причинам. У меня есть несколько требований:

  • Проверка: Расчет занимает много времени, поэтому мне нужно иметь возможность остановиться в любой точке и возобновить позже.
  • Разделяйте отдельные задачи как объекты: Это помогает мне хорошо понимать, где я нахожусь в вычислениях, и предлагает чистый способ выполнения контрольных точек с помощью сериализации.
  • Многопоточность: Задача явно смущающе параллельна, поэтому было бы неплохо ее использовать. Возможно, я бы хотел использовать для этого темы Boost.

Я хотел бы получить предложения о том, как на самом деле реализовать такую ​​систему. Способы, которыми я думал об этом:

  1. Реализация задач в виде простого стека. Когда вы нажимаете на задачу, которая нуждается в подрасчетах, она проверяет, есть ли у нее все подрасчеты, которые ей требуются. Если нет, то он создает подзадачи и выбрасывает их в стек. Если это так, то он вычисляет свой результат и извлекает себя из стека.
  2. Храните задачи в виде дерева и делайте что-то вроде шаблона посетителя на глубину. Это создаст все задачи в начале, а затем вычисления просто пройдут по дереву.

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

Мне кажется, я слишком обдумываю это, и уже есть простой, устоявшийся способ сделать что-то подобное. Есть ли один?


Технические детали, если они имеют значение:

  • Дерево задач имеет 5 уровней.
  • Коэффициент ветвления дерева действительно мал (скажем, между 2 и 5) для всех уровней, кроме самого низкого, который составляет порядка нескольких миллионов.
  • Каждая отдельная задача должна хранить только результат размером в десятки байт. Я не возражаю против использования диска в максимально возможной степени, если только он не снижает производительность.
  • Для отладки я должен иметь возможность вспомнить / пересчитать любую отдельную задачу.
  • Все вычисления являются дискретной математикой: вычисления с целыми числами, полиномами и группами. Никакой плавающей запятой вообще.

Ответы [ 2 ]

2 голосов
/ 20 июля 2011

есть основная задача, для получения которой требуется небольшое количество подсчетов.Эти субсчеты имеют субсубсчеты и так далее.Каждый расчет зависит только от вычислений под ним в дереве (при условии, что корневой узел является верхним).Не требуется обмена данными между филиалами.На более низких уровнях количество подзадач может быть очень большим ... бла-бла-возобновление, многопоточность и т. Д.

Поправьте меня, если я ошибаюсь, но мне кажется, что вы точноописание алгоритма уменьшения карты.

Просто прочитайте, что википедия говорит о сокращении карты:

Шаг «Карта»: главный узел принимает входные данные, разделяет их на более мелкие-проблемы и распределяет их по рабочим узлам.Рабочий узел может сделать это снова по очереди, что приведет к многоуровневой древовидной структуре.Рабочий узел обрабатывает эту меньшую проблему и передает ответ своему главному узлу.

Шаг «Уменьшить»: мастер-узел затем берет ответы на все подзадачи и объединяет их некоторым способом, чтобы получитьвывод - ответ на проблему, которую он изначально пытался решить.

Использование существующего каркаса mapreduce может сэкономить вам огромное количество времени.

Я просто Google "карта уменьшитьC ++ ", и я начинаю получать результаты, в частности, в Boost http://www.craighenderson.co.uk/mapreduce/

0 голосов
/ 20 июля 2011

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

Вам определенно не нужны миллионы потоков, связанных с процессором. Требуется не более N потоков, связанных с процессором, где N - это произведение количества процессоров и количества ядер на процессор на вашей машине. Немного превышайте N, и вы немного замедляете процесс. Превосходит N на много, и вы все сильно замедляете. Машина будет тратить почти все свое время на переключение потоков в контекст и из контекста, тратя очень мало времени на выполнение самих потоков. Значительно превышайте N, и вы, скорее всего, сломаете свою машину (или достигнете некоторого ограничения потоков). Если вы хотите обрабатывать много-много (и много-много) параллельных задач одновременно, вам нужно либо использовать несколько машин, либо использовать вашу видеокарту.

...