параллелизм при возможности
От: MadHuman Россия  
Дата: 06.05.17 13:19
Оценка:
Доброго дня коллеги!
Интересно, есть ли в .Net возможности (имею ввиду что-то готовое или близко к этому), обеспечивать параллелализм в алгоритмах
на основе техники упоминаемой в статье ?


суть техники — наличие примитива:
join( do_a, do_b )

Основной момент тут в том, что два замыкания потенциально могут выполниться параллельно: решение, использовать или нет параллельные потоки, принимается динамически, в зависимости от того, есть ли свободные ядра или нет. Идея в том, что вы можете с помощью join помечать в своей программе те места, где параллелизм может быть полезен, а затем позволить библиотеке во время выполнения решать, использовать ли его или нет.


Внутри join реализован с использованием техники, известной как перехват работы. Насколько мне известно, перехват работы был впервые представлен как часть проекта Cilk, и с тех пор стал довольно стандартной техникой (фактически название Rayon (англ. «вискоза», а «Cilk» аллюзия на «silk», т.е. «шёлк» — прим. перев.) — дань уважения Cilk).
Главная идея в том, что при каждом вызове join(a, b) мы определяем две задачи a и b, которые могут быть безопасно выполнены параллельно, но мы пока что не знаем, есть ли для этого свободные потоки. Всё, что делает текущий поток, это добавляет b в очередь «планируемой работы», а затем берёт, и немедленно выполняет a. В то же время существует пул других активных потоков (обычно по одному потоку на ядро ЦП, или что-то типа того). Как только какой-то из потоков освобождается, он идёт и копается в очередях «планируемой работы» других потоков: если там находится задача, свободный поток захватывает её и выполняет её сам. Так что в таком случае, пока первый поток занят выполнением a, другой поток может начать выполнение b.
Как только первый поток заканчивает a, он проверяет: начал ли кто-то другой выполнять b? Если нет, то он выполняет её сам. Если да, то ему нужно подождать, пока другой поток её закончит. Но пока первый поток ждёт, он может пойти и стащить работу у другого потока, тем самым способствуя завершению всего процесса работы в целом.


Первое что приходит в голову — создать для задачи b Task и дождаться его окончания, но в моём тесте — таск b всегда стартовал на другом потоке, и в итоге оверхид на синхронизацию (при условии относительно небольшой работы выполняемой в нём) будет заметен. это недостатки шедулинга тасков? или всегда таск стартует на другом потоке? или лучше такую технику реализовать как-то по другому?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.