Concurrency

37

Transcript of Concurrency

Page 1: Concurrency
Page 2: Concurrency

ConcurrencyExamples for .NET

Page 3: Concurrency
Page 4: Concurrency

Responsive

Page 5: Concurrency

PerformanceScalable algorithms

Page 6: Concurrency

Three pillars of Concurrency

Scalability (CPU) Parallel.For

Responsiveness Task async/await

Consistency lock Interlocked.* Mutex/Event/Semaphore Monitor

Page 7: Concurrency

Scalability

Page 8: Concurrency
Page 9: Concurrency

Which is fastest?

var ints = new int[InnerLoop];var random = new Random();for (var inner = 0; inner < InnerLoop; ++inner){    ints[inner] = random.Next();}// ------------------------------------------------var ints = new int[InnerLoop];var random = new Random();Parallel.For(    0,     InnerLoop,    i => ints[i] = random.Next()    );

Page 10: Concurrency

SHARED STATE Race condition

var ints = new int[InnerLoop];var random = new Random();for (var inner = 0; inner < InnerLoop; ++inner){    ints[inner] = random.Next();}// ------------------------------------------------var ints = new int[InnerLoop];var random = new Random();Parallel.For(    0,     InnerLoop,    i => ints[i] = random.Next()    );

Page 11: Concurrency

SHARED STATE Poor performancevar ints = new int[InnerLoop];var random = new Random();for (var inner = 0; inner < InnerLoop; ++inner){    ints[inner] = random.Next();}// ------------------------------------------------var ints = new int[InnerLoop];var random = new Random();Parallel.For(    0,     InnerLoop,    i => ints[i] = random.Next()    );

Page 12: Concurrency
Page 13: Concurrency

Then and now

Metric VAX-11/750 (’80)

Today Improvement

MHz 6 3300 550x

Memory MB 2 16384 8192x

Memory MB/s 13 R ~10000W ~2500

770x190x

Page 14: Concurrency

Then and now

Metric VAX-11/750 (’80)

Today Improvement

MHz 6 3300 550x

Memory MB 2 16384 8192x

Memory MB/s 13 R ~10000W ~2500

770x190x

Memory nsec 225 70 3x

Page 15: Concurrency

Then and now

Metric VAX-11/750 (’80)

Today Improvement

MHz 6 3300 550x

Memory MB 2 16384 8192x

Memory MB/s 13 R ~10000W ~2500

770x190x

Memory nsec 225 70 3x

Memory cycles

1.4 210 -150x

Page 16: Concurrency

299,792,458 m/s

Page 17: Concurrency
Page 18: Concurrency

Speed of light is too slow

Page 19: Concurrency

0.09 m/c

Page 20: Concurrency
Page 21: Concurrency

99% - latency mitigation

1% - computation

Page 22: Concurrency

2 Core CPU

RAM

L3L2

L1

CPU

L2

L1

CPU

Page 23: Concurrency

2 Core CPU – L1 Cache

L1

CPU

L1

CPU

new Random ()

new int[InnerLoop]

Page 24: Concurrency

4 Core CPU – L1 Cache

L1

CPU

L1

CPU

L1

CPU

L1

CPU

new Random ()

new int[InnerLoop]

Page 25: Concurrency

2x4 Core CPU

RAM

L3L2

L1

CPU

L2

L1

CPU

L2

L1

CPU

L2

L1

CPU

L3L2

L1

CPU

L2

L1

CPU

L2

L1

CPU

L2

L1

CPU

Page 26: Concurrency

Solution 1 – Locks

var ints = new int[InnerLoop];var random = new Random();Parallel.For(    0,     InnerLoop,    i => {lock (ints) {ints[i] = random.Next();}}    );

Page 27: Concurrency

Solution 2 – No sharing

var ints = new int[InnerLoop];Parallel.For( 0, InnerLoop, () => new Random(), (i, pls, random) => {ints[i] = random.Next(); return random;}, random => {} );

Page 28: Concurrency

Parallel.For adds overheadLevel0

Level1

Level2

ints[0]

ints[1]

Level2

ints[2]

ints[3]

Level1

Level2

ints[4]

ints[5]

Level2

ints[6]

ints[7]

Page 29: Concurrency

Solution 3 – Less overhead

var ints = new int[InnerLoop];Parallel.For( 0, InnerLoop / Modulus, () => new Random(), (i, pls, random) => { var begin = i * Modulus ; var end = begin + Modulus ; for (var iter = begin; iter < end; ++iter) { ints[iter] = random.Next(); } return random; }, random => {} );

Page 30: Concurrency

var ints = new int[InnerLoop];var random = new Random();for (var inner = 0; inner < InnerLoop; ++inner){    ints[inner] = random.Next();}

Page 31: Concurrency

Solution 4 – Independent runs

var tasks = Enumerable.Range (0, 8).Select ( i => Task.Factory.StartNew ( () => { var ints = new int[InnerLoop]; var random = new Random (); while (counter.CountDown ()) { for (var inner = 0; inner < InnerLoop; ++inner) { ints[inner] = random.Next(); } } }, TaskCreationOptions.LongRunning)) .ToArray ();Task.WaitAll (tasks);

Page 32: Concurrency

Parallel.For

Only for CPU bound problems

Page 33: Concurrency

Sharing is bad

Kills performanceRace conditions

Dead-locks

Page 34: Concurrency

Servers have natural concurrency

Avoid Parallel.For

Page 35: Concurrency

Act like an engineer

Measure before and after

Page 36: Concurrency

One more thing…

Page 37: Concurrency

Mårten Rånge

[email protected]