Std:: async - зависимое от реализации использование?
Я думал о std::async
и как его следует использовать в будущей реализации компилятора. Тем не менее, прямо сейчас я немного застрял в чем-то, что кажется конструктивным недостатком.
std::async
в значительной степени зависит от реализации, возможно, с двумя вариантами launch::async
, который запускает задачу в новый поток и тот, который использует пул потоков/планировщик задач.
Однако, в зависимости от того, какой из этих вариантов используется для реализации std::async
, использование будет сильно различаться.
Для варианта с потоковым пулом вы могли бы запускать множество небольших задач, не беспокоясь о накладных расходах, однако, что, если один из блоков задач в какой-то момент?
С другой стороны, вариант "запускать новый поток" не будет иметь проблем с задачами блокировки, с другой стороны, накладные расходы на запуск и выполнение задач будут очень высокими.
поток бассейн:
+ low-overhead, никогда не блокирует
запустить новый поток:
+ штраф с блоками, -высокая накладная
Таким образом, в основном в зависимости от реализации, способ, которым мы используем std::async
, будет очень осторожным. Если у нас есть программа, которая хорошо работает с одним компилятором, она может работать ужасно на другом.
Это по дизайну? Или я чего-то не хватает? Считаете ли вы это, как и я, большой проблемой?
В текущей спецификации я пропускаю что-то вроде std::oversubscribe(bool)
, чтобы разрешить реализацию в зависимом использовании std::async
.
EDIT: насколько я читал, стандартный документ С++ 11 не дает никаких намеков относительно того, могут ли задачи, отправленные на std::async
блокировать или нет.
Ответы
Ответ 1
std::async
задачи, запущенные с политикой std::launch::async
запускать "как будто в новом потоке", поэтому пулы потоков на самом деле не поддерживаются - среда выполнения должна будет снести и воссоздать все локальные переменные потока между выполнением каждой задачи, что не является простым.
Это также означает, что вы можете ожидать, что задачи, запущенные с помощью политики std::launch::async
, будут выполняться одновременно. Может быть задержка при запуске, и при переключении задач будет больше задач, чем процессоров, но они должны быть запущены, а не тупиковой ситуации, потому что один из них ждет другого.
Реализация может предложить предложить расширение, которое позволяет запускать ваши задачи в пуле потоков, и в этом случае для реализации семантики документируется эта реализация.
Ответ 2
Я бы ожидал, что реализация начнет создавать новые потоки и оставьте пул потоков в будущей версии С++, которая его стандартизирует. Существуют ли какие-либо реализации, которые используют пул потоков?
MSVC сначала использовал пул потоков на основе их Concurrency Runtime. Согласно STL Fixes В VS 2015, часть 2, это было удалено. Спецификация С++ оставила место для разработчиков, чтобы делать умные вещи, однако я не думаю, что это вполне достаточно для реализации этой пула потоков. В частности, я думаю, что спецификация все еще требовала, чтобы объекты thread_local
были уничтожены и перестроены, но этот пул потоков с ConcRT не поддержал бы это.