Переход от многопоточной программы к ЦПУ на 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.

  1. Есть ли способ (поскольку у меня уже есть отдельная вычислительная функция), чтобы переместить это легко, не изменяя весь код? Как функция, которая может запускать потоки в GPU таким же образом, что и boost (например, замена потока boost на поток GPU)?
  2. Кроме того, моя вычислительная функция осуществляет доступ к некоторым данным, загруженным в память (здесь ОЗУ), требует ли GPU эти данные для загрузки в память GPU, или он может получить доступ к ОЗУ (а затем в этом случае, какой из них быстрее)?
  3. И последний вопрос (хотя я почти уверен, что знаю ответ), возможно ли сделать его аппаратно независимым (чтобы мой код мог работать на Nvidia, ATI и т. Д.)?

Спасибо.

1 ответ

  • 1) Самое простое решение - использовать директиву #pragma (OpenACC), которая уже должна присутствовать в GCC7.

  • 2) ваши данные должны быть совместимы с графическим процессором, понимать структуру массива

  • 3) ваше "ядро" compute_desc должно быть совместимо с GPU, если вы не знаете, допустим, оно должно быть векторизовано компилятором.

Я надеюсь, что это немного поможет, я думаю, что небольшое руководство по OpenACC tuto должно стать лучшим решением для вас, CUDA/OpenCL должен появиться позже. Мои 2 цента

Другие вопросы по тегам