А Вы, случайно, не Цезарь?

Я вот, например - нет. Я имею в виду, что делать одновременно несколько дел, подобно известному римскому императору, не умею. Ну разве что самых элементарных (например, смотреть телевизор и завтракать). Но я не умею делать одновременно два или более дела, требующих обдумывания каждого из них - например, я не могу одновременно читать один текст и писать другой или участвовать в разговоре и решать задачу. Возможно, именно поэтому мне длительное время совсем не давалось параллельное программирование. Я понимал общие принципы, знал все нужны функции, но никак не мог построить в голове общую картину происходящего. У меня, получается, есть много потоков, которые что-то делают. Да еще часто с одними и теми же данными. При этом не понятно с какой скоростью они это делают, кому ОС отдаст больше времени, когда будет переключаться с одного потока на другой. Я ощущал себя кем-то вроде художника, который раньше рисовал картины классическим способом "1 мольберт - 1 кисть - 1 палитра", а тут ему заказали 100 картин, приделали сотню рук и сказали - рисуй, давай. При этом голова по-прежнему осталась одна и как держать в фокусе 100 объектов и координировать 100 действий одновременно - непонятно. Я чувствовал, что что-то здесь не так. Должен был быть другой путь.

И он нашелся. Им оказалась библиотека Intel TBB с её концепцией планировщика задач (Task Scheduler). Для тех, кто с TBB не знаком я коротко объясню суть этого паттерна: вы абстрагируетесь от количества логических\физических процессоров, от числа потоков операционной системы и создаёте свой алгоритм в терминах "задач". Задаче передаётся что-то на вход, она что-то делает и возвращает что-то на выход. Задач может быть много (сильно больше числа процессоров), они могут быть независимы друг от друга, или порождаться друг другом.

На первый взгляд может показаться, что всё это ничем не отличается от классических потоков со всеми вытекающими плюсами и минусами. Но это только на первый взгляд. Копнув глубже, я понял, что уже не чувствую себя художником из примера выше. Я чувствую себя владельцем крупной арт-мастерской. Мне ничего не нужно делать самому! У меня есть некоторые производственные мощности и очень грамотный управляющий. Когда мне приходит заказ на 100 картин, я вызываю его к себе и говорю : "Вот что надо сделать. Вот ресурсы. Вот инструкции по работе. Вперед!". И дальше я могу удаляться на свою любимый тропический остров лежать в шезлонге, попивая мартини, и знать, что работа будет выполнена. Управляющий сам оценит объем работ и имеющиеся ресурсы (CPU), наймет нужное количество работников (Tasks), проследит, чтобы каждому из них достались средства для работы и достачный (но посильный) объем задач. При этом по ходу работы он будет контролировать нагрузку, перекидывать задачи и ресурсы для достижения равномерной загруженности, подстёгивать лентяев и разгружать перегруженных трудяг. Вся работа будет выполнена строго по моим инструкциям: что должно делаться последовательно - будет сделанно именно так, что может быть распараллелено - обязательно будет. Более того, я уверен, что этот управляющий сделает всё вышеуказанное намного лучше меня - ведь на его создание и обучение очень много умных людей (сильно умнее меня) потратили очень много времени. Вряд ли я обладаю знаниями того же уровня для координации всей этой работы.



Лично мне такой подход к параллельному программированию нравится намного больше. Я не привязан к конкретным потокам, я не сильно беспокоюсь о низкоуровневых деталях. Конечно, кое-какие заморочки с синхронизацией остались (куда же без них!), но воспринимаются они совсем по-другому. В общем, я остался приятно удивлен библиотекой Intel TBB и советую всем, кто с ней еще не знаком - обязательно взглянуть.

Начать читать можно где-то отсюда.
Советую начинать с Tutorial - там всё коротко и весьма понятно. Если решите использовать библиотеку серьёзно - читайте также полную документацию и Design Patterns
Para obter informações mais completas sobre otimizações do compilador, consulte nosso aviso de otimização.