2015-11-19 2 views
4

Предположим, у меня есть эта функция big_task(), которую я могу разделить между потоками для ускорения.Многопоточность для выполнения одной задачи в C++

Способ решения этой проблемы при многопоточности состоит в вызове _beginthread() для каждой задачи функции, а затем ждать окончания всех потоков, не так ли?

Как я узнаю, что это будет эффективно и действительно поможет свести к минимуму big_task() время работы?

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

Еще один вопрос, при кодировании в Windows лучше ли использовать CreateThread(), а не _beginthread()? Я пишу кросс-платформенные приложения, но если CreateThread() более эффективен, чем я мог бы специализировать мой код для использования в Windows.

+0

Можете ли вы пролить свет на тип задач? (networking, db-access, disk-io, cpu time?) – Stefan

+2

, если вы используете C++ 11, я считаю, что вместо этого вы можете использовать 'std :: thread'. – Default

+0

Ну, во-первых, если вы работаете в многопроцессорной/многоядерной системе, то, конечно, многопоточность будет быстрее. –

ответ

2

Я надеюсь, что это поможет вам начать работу.

Для достижения ускорения по однопоточному подходу необходим многоядерный процессор. На одноядерном процессоре дополнительный поток не увеличит скорость вычислений, но может помочь сделать другие функции гладкими (например, GUI) в одно и то же время при интенсивной работе с ЦП.

Для использования многоядерного процессора вам необходимо разделить «большую задачу» на куски, которые могут быть выполнены в одно и то же время и не влияют друг на друга.

Общий поток:

  1. Положите кусочки в контейнер. Установите их статус «доступно».
  2. Создайте столько потоков, сколько хотите (до фактического количества ядер процессора полезно).
  3. Это функция потока. Они выполняются параллельно.

    1. Попытайтесь захватить первый «доступный» кусок от контейнера и сделать его «занятым». Если не найден «доступный» фрагмент, выйдите из потока.
    2. Обработать кусок и сделать его «готовым».
    3. Вернуться к (4)
  4. В основной нити ожидания для всех рабочих потоков, чтобы закончить. Вы можете ждать в цикле, спящем секунду на каждом шаге, проверяя, нажата ли Ctrl-C. Или просто «присоединитесь» (дождитесь окончания потока) на всех потоках.

  5. Соберите все куски вместе и используйте результат ваших вычислений.

Помните, что вам нужно следить за несколькими потоками, обращаясь к тем же данным, потому что они могут мешать друг другу. Например, несколько потоков могут принимать один и тот же кусок для обработки в одно и то же время. Эта проблема может быть решена с помощью мьютекса (см. boost::mutex).

Существуют и другие подходы к решению этой проблемы. Вы можете поместить свои куски в очередь сообщений (FIFO) и позволить потокам вытолкнуть их из очереди и поместить результаты в другую очередь. Если вы расширяете эту очередь по сети, вы можете использовать несколько ПК, выполняющих работу.

Для портативности вы можете использовать boost::thread.

Это также полезно: boost::thread_group

5

Способ решения этой проблемы при многопоточности заключается в вызове _beginthread() для каждой задачи функции, а затем ждать завершения всех потоков, не так ли?

таким образом вы будете распараллеливать свою большую функцию, так что да, это правда.

Как я узнаю, что это будет эффективно и действительно поможет минимизировать время работы big_task()?

вы должны продумать его. Если ваша большая функция выполняет код на процессоре без операций ввода-вывода, рассмотрите возможность создания такого же количества потоков, как количество ядер в вашем CPU.

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

процессор с большим количеством ядер, безусловно, будет быстрее, чем тот, с меньше, вы можете посмотреть в PPL (только выиграет), библиотеки TBB, OpenMP, которая гарантирует, что задачи выполняются эффективно на основе количества ядер процессора.

Еще один вопрос, при кодировании в Windows лучше использовать CreateThread(), а не _beginthread()? Я пишу кросс-платформенные приложения, но если CreateThread() более эффективен, чем я мог бы специализировать мой код для использования в Windows.

Если вы хотите использовать кросс-платформу, используйте std :: thread или boost для этого.

+0

Im не форсированный вентилятор. Что случилось с _beginthread? – Pilpel

+0

@Pilpel, потому что его окна работают только, под эквивалентом linux - библиотека pthreads. std :: thread будет работать на windows, linux, ... – marcinj

+0

Итак _beginthread() считается устаревшим? – Pilpel

Смежные вопросы