4. Накладые расходы при паралелизме Необходимо деление операций Выполнения потоков вызывает лишние накладные расходы Чем больше потоков тем больше лишних расходов Для быстрого запуска/выполнения потоков необходимо уменьшить накладные расходы связанные с этим Overhead Overhead Overhead Overhead Overhead Overhead Work Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead Overhead
9. Новые примитивы синхронизации Использованы при разработке PLINQ и TPL Для того чтобы решать большинство задач в многопоточности Thread-safe, scalable collections IProducerConsumerCollection<T> ConcurrentQueue<T> ConcurrentStack<T> ConcurrentBag<T> ConcurrentDictionary<TKey,TValue> Phases and work exchange Barrier BlockingCollection<T> CountdownEvent Partitioning {Orderable}Partitioner<T> Partitioner.Create Exception handling AggregateException Initialization Lazy<T> LazyInitializer.EnsureInitialized<T> ThreadLocal<T> Locks ManualResetEventSlim SemaphoreSlim SpinLock SpinWait Cancellation CancellationToken{Source}
10. Распараллеливаем циклы Control flow is a primary source of work Распаралеливаем если итерации независимы «Синхронное» поведение, поток выполнения не пройдет пока цикл не выполнится Возможности Cancelation, breaking, task-local state, scheduling, degree of parallelism Поддержка профайлера Visual Studio 2010 (как у PLINQ) foreach(var item in data) { work(item); } for (int i = 0; i < n; i++) { work(i); } StatementA(); StatementB; StatementC(); Parallel.ForEach(data, item=> { work(item); }); Parallel.For(0, n, i=> { work(i); }); Parallel.Invoke( () => StatementA(), () => StatementB, () => StatementC());
11.
12. Легко с LINQ на PLINQ PLINQ может выполнить все LINQ запросы Простые запросы – проще выполнить Разбивайте сложные запросы на более простые, так чтобы только та часть которую нужно распралелить была PLINQ: src.Select(x => Foo(x)) .TakeWhile(x => Filter(x)) .AsParallel() .Select(x => Bar(x)) .ToArray();
16. Cсылки и источники DevCenter http://msdn.com/concurrency Исходные коды примеров http://code.msdn.microsoft.com/ParExtExamples Блоги http://blogs.msdn.com/pfxteam Parallel stack Доклады, видео http://channel9.msdn.com/learn http://microsoftpdc.com/
Проблемы параллелизма свзязаны с дополнительными накладными расходами. Потоки, и многопоточность имеют свою цену. Например есть расходы с созданием, завршением потока, созданием делегата который выполняет работу. Расходы связанные с выполнением и conceptional overhead.Предположим есть какая-то задача, если это цельная задача, она будет использовать один поток.Для того чтобы выполнить эту задачу в 4 потока необхожимо ее разделить на 4 части
Попробую расказать коротко про тредпул в 3.5. Основная идея – треды управляются системой и это потому что треды относительно дорогоие, дорогоие для создание и для уничтожения, дорого создавать много потоков и дорого переключатся между ними. И как результат мы старались выполнять работу как можно меньшим числом потоков. И на самом деле это касается не только тредпула но и любых других потоков.Блокировки замедляют выполнение задач так как тредам приходится ждать ресурсов.Это также как и в реальном мире. На примере комманды разработчиков. Например задача может быть сделана двумя разработчикам достаточно эффективно. Мы хотим увеличить производительность и уменьшить время. Добавляя новых разработчиков к комманде мы достигаем этого но требуется все больше накладных расходов на совещания и прочее.
Lock-free queue – removed lock to reduce contention, instead used interlocked operationsLocal queue – LIFO order because cache locality, may be data cached by CPU(L1, L2, L3 caches)When work thread has no data it asks first local queue that global, and then it steals most old items from local queue of another thread