Переход от многопоточной программы к ЦПУ на C++
Я создал программу, которая должна вызывать функцию несколько раз (много!!) с разными входными параметрами. Чтобы ускорить процесс, я использовал многопоточность так:
std::vector< MTDPDS* > mtdpds_list;
boost::thread_group thread_gp;
for (size_t feat_index = 0; feat_index < feat_parser.getNumberOfFeat(); ++feat_index)
{
Feat* feat = feat_parser.getFeat(static_cast<unsigned int>(feat_index));
// != 0 has been added to avoid a warning message during compilation
bool rotatedFeat = (feat->flag & 0x00000020) != 0;
if (!rotatedFeat)
{
Desc* desc = new Desc(total_sb, ob.size());
MTDPDS* processing_data = new MTDPDS();
processing_data->feat = feat;
processing_data->desc = desc;
processing_data->img_info = image_info;
processing_data->data_op = &data_operations;
processing_data->vecs_bb = vecs_bb;
mtdpds_list.push_back(processing_data);
thread_gp.add_thread(new boost::thread(compute_desc, processing_data));
}
}
// Wait for all threads to complete
thread_gp.join_all();
Этот код является частью гораздо большего кода, поэтому не стоит слишком беспокоиться об именах переменных и т. Д. Важно то, что я создаю объект (MTDPDS
) для каждого потока, содержащего входные и выходные параметры, затем создайте поток, вызывающий мою функцию обработки compute_desc
и дождитесь завершения всех потоков, прежде чем продолжить.
Тем не менее, мой for
цикл имеет около 2000+ итераций, что означает, что я запускаю около 2000+ потоков. Я запускаю свой код в кластере, поэтому он довольно быстрый, хотя IMO все еще занимает слишком много времени.
Я хотел бы перенести эту часть в GPU (так как в ней гораздо больше ядер), хотя я новичок в программировании на GPU.
- Есть ли способ (поскольку у меня уже есть отдельная вычислительная функция), чтобы переместить это легко, не изменяя весь код? Как функция, которая может запускать потоки в GPU таким же образом, что и boost (например, замена потока boost на поток GPU)?
- Кроме того, моя вычислительная функция осуществляет доступ к некоторым данным, загруженным в память (здесь ОЗУ), требует ли GPU эти данные для загрузки в память GPU, или он может получить доступ к ОЗУ (а затем в этом случае, какой из них быстрее)?
- И последний вопрос (хотя я почти уверен, что знаю ответ), возможно ли сделать его аппаратно независимым (чтобы мой код мог работать на Nvidia, ATI и т. Д.)?
Спасибо.
1 ответ
1) Самое простое решение - использовать директиву #pragma (OpenACC), которая уже должна присутствовать в GCC7.
2) ваши данные должны быть совместимы с графическим процессором, понимать структуру массива
3) ваше "ядро" compute_desc должно быть совместимо с GPU, если вы не знаете, допустим, оно должно быть векторизовано компилятором.
Я надеюсь, что это немного поможет, я думаю, что небольшое руководство по OpenACC tuto должно стать лучшим решением для вас, CUDA/OpenCL должен появиться позже. Мои 2 цента