Какие подходы можно порекомендовать для ускорения массивной (процессорной) параллельной программы?

Моя программа нейроэволюции (C ++) в настоящее время ограничена небольшими наборами данных, и у меня есть проекты для нее, которые (на моей нынешней рабочей станции / облачной компоновке) будут выполняться месяцами. Самым большим узким местом является НЕ оценка сети или эволюционных процессов; это размер наборов данных. Чтобы получить пригодность сети-кандидата, она должна быть оценена для КАЖДОЙ записи в наборе.

В идеальном мире у меня был бы доступ к облачному экземпляру виртуальной машины с 1 ядром для каждой записи в наборе данных Cover Type из 15 120 записей. Однако самые большие виртуальные машины, которые я обнаружил, — 112-ядерные. В настоящее время моя программа использует OpenMP для распараллеливания цикла for, реализующего оценку всех записей. Ускорение равно количеству ядер. Кроссовер / мутация является последовательной, но ее можно легко распараллелить для оценки каждого человека (100–10000 из них).

Самая большая проблема заключается в том, как сеть должна была быть реализована. Обращение к сети напрямую из этой структуры.

    struct DNA {
vector<int> sizes;
vector<Function> types;
vector<vector<double>> biases;
vector<vector<vector<double>>> weights;
};

Ускорение GPU оказывается невозможным. Структуры программы должны состоять из многомерных типов данных, размеры которых могут различаться (не каждый слой имеет одинаковый размер). Я выбрал векторы STL … ПОТОМ понял, что ядра не могут быть переданы или обратиться к ним. Стандартные операции (вектор / матрица) потребуют преобразования данных, передачи, выполнения и обратного преобразования. Это просто не жизнеспособно.

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

  1. Инициализируйте «главный» экземпляр облака и используйте его для запуска 100–10000 экземпляров меньшего размера. Каждый из них будет иметь копию набора данных в памяти, и его нужно будет удалить, как только программа найдет решение.
  2. SBC с их низкими затратами и растущими спецификациями могут позволить построить небольшой домашний вычислительный кластер, устраняя любые проблемы с безопасностью в облаке и предоставляя мне больший контроль над оборудованием.
  3. Я понятия не имею, что я делаю, невозможно вырастить большие нейронные сети (практически) без ускорения GPU, я не смог понять, что библиотека «тяги» может позволить векторному коду работать на GPU, и я не имею не сделал мою домашнюю работу.

-1

Решение

Глядя на то, что вы описали, я не думаю, что ускорение GPU невозможно. Мой любимый подход — OpenCL, но даже если вы используете CUDA, вы не можете легко использовать C ++ STL для этой цели. Но если вы преодолеете препятствие на пути преобразования вашего кода C ++ в структуры данных C (т.е. float, double, или же int и их массивы, а не vector<> типы, и переопределить ваш vector<Function> в более примитивные типы), использование GPU должно быть легким, особенно если ваша программа в основном выполняет матричные операции. Но вы можете знать, что архитектура GPU отличается от CPU. Если ваша логика имеет много ветвлений (то есть, структуры if-then-else), производительность в GPU не будет хорошей.

1

Другие решения

GPU гораздо более способный, чем вы думали. Вся память в GPU распределяется динамически, что означает, что вы можете выделить столько памяти, сколько захотите. Если вы хотите указать разный размер для каждого потока, просто сохраните их в массиве и используйте идентификатор потока для индексации. Более того, вы даже можете хранить сеть в разделяемой памяти и оценивать записи по потокам для ускорения доступа к памяти. Как вы упомянули, наиболее удобный способ — использовать библиотеку тяги. Вам не нужно понимать, как это реализовано, если ваша цель не изучать GPU. Вам также не нужно беспокоиться о производительности, потому что она оптимизирована профессиональными экспертами по GPU (многие из Nvidia, которые создают GPU). Конструкция Thrust очень похожа на STL, поэтому ее легко освоить, если вы знакомы с C ++.

0

По вопросам рекламы [email protected]