Паралелізм та concurrency -- напрямок, в якому технології програмування прямують зараз і, без сумніву, прямуватимуть в майбутньому. Багатоядерними процесорами оснащуються комп'ютери навіть початкового рівня, що відкриває можливості для створення швидких ефективних програм із "живими" інтерфейсами. Тому навіть ті розробники, які раніше не стикались із concurrent кодом, будуть все частіше і частіше програмувати із врахуванням паралелізму. В доповіді буде розглянуто шаблони паралельного програмування, способи асинхронного програмування, а також тенденції окремих сучасних технологій в області паралелізму та асинхронності. Слухачі зможуть отримати знання про основні способи організації паралельних обчислень у desktop-, web- і серверних аплікаціях, засоби досягнення responsive GUI, техніки вирішення проблем, що виникають у concurrent програмуванні.
8. Основні поняття
- Concurrency
- Many interleaved threads of control
- Parallelism
- Same result, but faster
- Concurrency != Parallelism
- It is not always necessary to care about concurrency
while implementing parallelism
- Multithreading
- Asynchrony
13. Isolation
- Avoiding shared state
- Own copy of state
- Examples:
- process isolation
- intraprocess isolation
- by convention
14. Immutability
- Multiple read -- not a problem!
- All functions are pure
- Requires immutable collections
- Functional way: Haskell, F#, Lisp
15. Synchronization
- The only thing that remains to deal with
shared mutable state
- Kinds:
- data synchronization
- control synchronization
16. Data synchronization
- Why? To avoid race conditions and data
corruption
- How? Mutual exclusion
- Data remains consistent
- Critical regions
- locks, monitors, critical sections, spin locks
- Code-centered
- rather than associated with data
18. Control synchronization
- To coordinate control flow
- exchange data
- orchestrate threads
- Waiting, notifications
- spin waiting
- events
- alternative: continuations
19. Three ways to manage state
- Isolation: simple, loosely coupled, highly
scalable, right data structures, locality
- Immutability: avoids sync
- Synchronization: complex, runtime overheads,
contention
- in that order
28. CoBegin
var firstDataset = new DataItem[1000];
var secondDataset = new DataItem[1000];
var thirdDataset = new DataItem[1000];
Parallel.Invoke(
() => Process(firstDataset),
() => Process(secondDataset),
() => Process(thirdDataset)
);
29. Parallel For
var items = new DataItem[1000 * 1000];
// ...
Parallel.For(0, items.Length,
i =>
{
Process(items[i]);
});
34. Declarative parallelism
var items = new DataItem[1000 * 1000];
// ...
var validItems =
from item in items.AsParallel()
let processedItem = Process(item)
where processedItem.Property > 42
select Convert(processedItem);
foreach (var item in validItems)
{
// ...
}
35. Data parallelism
Challenges
- Partitioning
- Scheduling
- Ordering
- Merging
- Aggregation
- Concurrency hazards: data races, contention
36. Task parallelism
How?
- Programs are already functionally partitioned:
statements, methods etc.
- Run independent pieces in parallel
- Control synchronization
- State isolation
52. Producer/consumer
var lines =
new BlockingCollection<string>();
Task.Factory.StartNew(() =>
{
foreach (var line in File.ReadLines(...))
lines.Add(line);
lines.CompleteAdding();
});
53. Producer/consumer
var dataItems =
new BlockingCollection<DataItem>();
Task.Factory.StartNew(() =>
{
foreach (var line in
lines.GetConsumingEnumerable()
)
dataItems.Add(Parse(line));
dataItems.CompleteAdding();
});
54. Producer/consumer
var dbTask = Task.Factory.StartNew(() =>
{
foreach (var item in
dataItems.GetConsumingEnumerable()
)
WriteToDatabase(item);
});
dbTask.Wait();
56. Message based parallelism
- Accessing shared state vs. local state
- No distinction, unfortunately
- Idea: encapsulate shared state changes into
messages
- Async events
- Actors, agents
60. Thread local state
- A way to achieve isolation
var parser = new ThreadLocal<Parser>(
() => CreateParser());
Parallel.ForEach(items,
item => parser.Value.Parse(item));