SlideShare a Scribd company logo
1 of 95
C++ Concurrency in Action Study
C++ Korea
C++ Korea
C++ Concurrency in Action
Study C++ Korea 박 동하 (luncliff@gmail.com)
C++ Korea 최두선 ( returns@lycos.co.kr )
C++ Concurrency in Action Study
C++ Korea
Definition and
consequences
C++ Concurrency in Action Study
C++ Korea
Blocking
3
C++ Concurrency in Action Study
C++ Korea
non-Blocking
4
C++ Concurrency in Action Study
C++ Korea
blocking, non-blocking ?? sync, async
5
C++ Concurrency in Action Study
C++ Korea
Implementation of a spin-lock mutex using
std::atomic_flag
6
C++ Concurrency in Action Study
C++ Korea
Lock-free Data Structures
7
C++ Concurrency in Action Study
C++ Korea
Lock-free Data Structures
8
C++ Concurrency in Action Study
C++ Korea
wait-free data structures
9
C++ Concurrency in Action Study
C++ Korea
The pros and cons of lock-free data stucture
10
C++ Concurrency in Action Study
C++ Korea
live lock
11
C++ Concurrency in Action Study
C++ Korea
Definitions and Consequences
12
C++ Concurrency in Action Study
C++ Korea
Writing a thread-safe
stack without locks
C++ Concurrency in Action Study
C++ Korea
Writing a thread-safe
queue without locks
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
15
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
16
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
17
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
18
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
19
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
20
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
21
Thread 1 Thread 2
push( ‘A’ ); push( ‘B’ );
1
std::shared_ptr<T> new_data( std::make_shared<T>(
new_value ) );
2 node* p = new node;
3 node* const old_tail = tail.load();
4
std::shared_ptr<T> new_data( std::make_shared<T>(
new_value ) );
5 node* p = new node;
6 node* const old_tail = tail.load();
7 old_tail->data.swap( new_data );
8 old_tail->next = p;
9 tail.store( p );
10 old_tail->data.swap( new_data );
11 old_tail->next = p;
12 tail.store( p );
queue
Node
<- HEAD
<- TAIL
Thread 1
new_data `A`
p
new
node1
old_tail Node
Thread 2
new_data
p
old_tail
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
22
Thread 1 Thread 2
push( ‘A’ ); push( ‘B’ );
1
std::shared_ptr<T> new_data( std::make_shared<T>(
new_value ) );
2 node* p = new node;
3 node* const old_tail = tail.load();
4
std::shared_ptr<T> new_data( std::make_shared<T>(
new_value ) );
5 node* p = new node;
6 node* const old_tail = tail.load();
7 old_tail->data.swap( new_data );
8 old_tail->next = p;
9 tail.store( p );
10 old_tail->data.swap( new_data );
11 old_tail->next = p;
12 tail.store( p );
queue
Node
<- HEAD
<- TAIL
Thread 1
new_data `A`
p
new
node1
old_tail Node
Thread 2
new_data `B`
p
new
node2
old_tail Node
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
23
Thread 1 Thread 2
push( ‘A’ ); push( ‘B’ );
1
std::shared_ptr<T> new_data( std::make_shared<T>(
new_value ) );
2 node* p = new node;
3 node* const old_tail = tail.load();
4
std::shared_ptr<T> new_data( std::make_shared<T>(
new_value ) );
5 node* p = new node;
6 node* const old_tail = tail.load();
7 old_tail->data.swap( new_data );
8 old_tail->next = p;
9 tail.store( p );
10 old_tail->data.swap( new_data );
11 old_tail->next = p;
12 tail.store( p );
queue
Node ’A’ <- HEAD
new node1
<- TAIL
Thread1
Thread 1
new_data `A`
p
new
node1
old_tail Node
Thread 2
new_data `B`
p
new
node2
old_tail Node
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
24
Thread 1 Thread 2
push( ‘A’ ); push( ‘B’ );
1
std::shared_ptr<T> new_data( std::make_shared<T>(
new_value ) );
2 node* p = new node;
3 node* const old_tail = tail.load();
4
std::shared_ptr<T> new_data( std::make_shared<T>(
new_value ) );
5 node* p = new node;
6 node* const old_tail = tail.load();
7 old_tail->data.swap( new_data );
8 old_tail->next = p;
9 tail.store( p );
10 old_tail->data.swap( new_data );
11 old_tail->next = p;
12 tail.store( p );
queue
Node ’B’ <- HEAD
New Node2
<- TAIL
Thread2
new node1 Thread1
Thread 1
new_data `A`
p
new
node1
old_tail Node
Thread 2
new_data `B`
p
new
node2
old_tail Node
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
25
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
26
Thread 1 Thread 2
pop() pop()
node* old_head = pop_head(); node* old_head = pop_head();
1
node* pop_head()
{
node* const old_head=head.load();
if( old_head == tail.load() )
{
return nullptr
}
2
node* pop_head()
{
node* const old_head=head.load();
if( old_head == tail.load() )
{
return nullptr
}
3
head.store( old_head->next );
return old_head;
}
4
head.store( old_head->next );
return old_head;
}
queue
Node ’A’ <- HEAD
Node2 <- TAIL
Thread 1
old_head Node
Thread 2
old_head
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
27
Thread 1 Thread 2
pop() pop()
node* old_head = pop_head(); node* old_head = pop_head();
1
node* pop_head()
{
node* const old_head=head.load();
if( old_head == tail.load() )
{
return nullptr
}
2
node* pop_head()
{
node* const old_head=head.load();
if( old_head == tail.load() )
{
return nullptr
}
3
head.store( old_head->next );
return old_head;
}
4
head.store( old_head->next );
return old_head;
}
queue
Node ’A’ <- HEAD
Node2 <- TAIL
Thread 1
old_head Node
Thread 2
old_head Node
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
28
Thread 1 Thread 2
pop() pop()
node* old_head = pop_head(); node* old_head = pop_head();
1
node* pop_head()
{
node* const old_head=head.load();
if( old_head == tail.load() )
{
return nullptr
}
2
node* pop_head()
{
node* const old_head=head.load();
if( old_head == tail.load() )
{
return nullptr
}
3
head.store( old_head->next );
return old_head;
}
4
head.store( old_head->next );
return old_head;
}
queue
Node2
<- HEAD
<- TAIL
Node ’A’
Thread 1
old_head Node ‘A’
Thread 2
old_head Node ‘A’
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
29
Thread 1 Thread 2
pop() pop()
node* old_head = pop_head(); node* old_head = pop_head();
1
node* pop_head()
{
node* const old_head=head.load();
if( old_head == tail.load() )
{
return nullptr
}
2
node* pop_head()
{
node* const old_head=head.load();
if( old_head == tail.load() )
{
return nullptr
}
3
head.store( old_head->next );
return old_head;
}
4
head.store( old_head->next );
return old_head;
}
queue
Node2
<- HEAD
<- TAIL
Node ’A’
Thread 1
old_head Node ‘A’
Thread 2
old_head Node ‘A’
C++ Concurrency in Action Study
C++ Korea
A single-producer, single-consumer lock free queue
30
Thread 1 Thread 2
pop() pop()
node* old_head = pop_head();
1 node* old_head = pop_head();
2
if( !old_head )
{
return std::shared_ptr<T>();
}
std::shared_ptr<T> const res ( old_head->data );
delete old_head;
return res;
3
if( !old_head )
{
return std::shared_ptr<T>();
}
std::shared_ptr<T> const res ( old_head->data );
delete old_head;
return res;
queue
Node2
<- HEAD
<- TAIL
Node ’A’
Thread 1
old_head Node ‘A’
res Node ‘A’
Thread 2
old_head Node ‘A’
res Node ‘A’
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
31
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
32
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
33
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
34
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
35
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
36
Thread 1 Thread 2
push() pop()
std::unique_ptr<T> new_data(new T(new_value));
counted_node_ptr new_next;
new_next.ptr = new node;
new_next.external_count = 1;
for(;;)
{
node* const old_tail = tail.load();
T* old_data = nullptr;
if( old_tail->data.compare_exchange_strong(
old_data, new_data.get() ) )
{
1
node* old_head = pop_head();
if( !old_head )
{
return std::shared_ptr<T>();
}
std::shared_ptr<T> const res( old_head->data );
delete old_head;
return res;
2
old_tail->next = new_next;
tail.store( new_next.ptr );
new_data.release();
break;
}
}
queue
Node
<- HEAD
<- TAIL
Thread 1
new_data
old_tail
Thread 2
old_head
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
37
Thread 1 Thread 2
push() pop()
std::unique_ptr<T> new_data(new T(new_value));
counted_node_ptr new_next;
new_next.ptr = new node;
new_next.external_count = 1;
for(;;)
{
node* const old_tail = tail.load();
T* old_data = nullptr;
if( old_tail->data.compare_exchange_strong(
old_data, new_data.get() ) )
{
1
node* old_head = pop_head();
if( !old_head )
{
return std::shared_ptr<T>();
}
std::shared_ptr<T> const res( old_head->data );
delete old_head;
return res;
2
old_tail->next = new_next;
tail.store( new_next.ptr );
new_data.release();
break;
}
}
queue
Node ‘A’
<- HEAD
<- TAIL
Thread 1
new_data ‘A’
old_tail Node
Thread 2
old_head
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
38
Thread 1 Thread 2
push() pop()
std::unique_ptr<T> new_data(new T(new_value));
counted_node_ptr new_next;
new_next.ptr = new node;
new_next.external_count = 1;
for(;;)
{
node* const old_tail = tail.load();
T* old_data = nullptr;
if( old_tail->data.compare_exchange_strong(
old_data, new_data.get() ) )
{
1
node* old_head = pop_head();
if( !old_head )
{
return std::shared_ptr<T>();
}
std::shared_ptr<T> const res( old_head->data );
delete old_head;
return res;
2
old_tail->next = new_next;
tail.store( new_next.ptr );
new_data.release();
break;
}
}
queue
<- HEAD
<- TAIL
Node ‘A’
Thread 1
new_data ‘A’
old_tail Node
Thread 2
old_head Node
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
39
Thread 1 Thread 2
push() pop()
std::unique_ptr<T> new_data(new T(new_value));
counted_node_ptr new_next;
new_next.ptr = new node;
new_next.external_count = 1;
for(;;)
{
node* const old_tail = tail.load();
T* old_data = nullptr;
if( old_tail->data.compare_exchange_strong(
old_data, new_data.get() ) )
{
1
node* old_head = pop_head();
if( !old_head )
{
return std::shared_ptr<T>();
}
std::shared_ptr<T> const res( old_head->data );
delete old_head;
return res;
2
old_tail->next = new_next;
tail.store( new_next.ptr );
new_data.release();
break;
}
}
queue
<- HEAD
<- TAIL
Node ‘A’
Thread 1
new_data ‘A’
old_tail Node
Thread 2
old_head Node
C++ Concurrency in Action Study
C++ Korea
Implementing push() for a lock free queue
40
C++ Concurrency in Action Study
C++ Korea
Implementing push() for a lock free queue
41
C++ Concurrency in Action Study
C++ Korea
Implementing push() for a lock free queue
42
C++ Concurrency in Action Study
C++ Korea
Implementing push() for a lock free queue
43
C++ Concurrency in Action Study
C++ Korea
Poping a node from lock-free queue
44
C++ Concurrency in Action Study
C++ Korea
Releasing a node reference
45
C++ Concurrency in Action Study
C++ Korea
Obtaining a new reference to a node
46
C++ Concurrency in Action Study
C++ Korea
Freeing an external counter to a node
47
C++ Concurrency in Action Study
C++ Korea
lock free ???
48
C++ Concurrency in Action Study
C++ Korea
Making The Queue Lock-free By Helping out Another
Thread
49
C++ Concurrency in Action Study
C++ Korea
pop() modified to allow helping on push() side
50
C++ Concurrency in Action Study
C++ Korea
pop() modified to allow helping on push() side
51
C++ Concurrency in Action Study
C++ Korea
sample push() with helping for lock-free queue
52
C++ Concurrency in Action Study
C++ Korea
sample push() with helping for lock-free queue
53
C++ Concurrency in Action Study
C++ Korea
sample push() with helping for lock-free queue
54
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
55
Thread 1 Thread 2
push( `A` ) push( `B` )
1
std::unique_ptr<T> new_data( new T( new_value ) );
counted_node_ptr new_next;
new_next.ptr = new node;
new_next.external_count = 1;
counted_node_ptr old_tail = tail.load();
for(;;)
{
increase_external_count( tail,old_tail );
T* old_data = nullptr;
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
2
std::unique_ptr<T> new_data( new T( new_value ) );
counted_node_ptr new_next;
new_next.ptr = new node;
new_next.external_count = 1;
counted_node_ptr old_tail = tail.load();
for(;;)
{
increase_external_count( tail,old_tail );
T* old_data = nullptr;
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
queue
Node 1
<- HEAD
<- TAIL
Thread 1 ‘A’
old_tail TAIL
old_next
new_next 1, Node2
Thread 2 ‘B’
old_tail
old_next
new_next
Node1
`A`,
0, nullptr
Node2
``,
0, nullptr
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
56
Thread 1 Thread 2
push( `A` ) push( `B` )
1
std::unique_ptr<T> new_data( new T( new_value ) );
counted_node_ptr new_next;
new_next.ptr = new node;
new_next.external_count = 1;
counted_node_ptr old_tail = tail.load();
for(;;)
{
increase_external_count( tail,old_tail );
T* old_data = nullptr;
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
2
std::unique_ptr<T> new_data( new T( new_value ) );
counted_node_ptr new_next;
new_next.ptr = new node;
new_next.external_count = 1;
counted_node_ptr old_tail = tail.load();
for(;;)
{
increase_external_count( tail,old_tail );
T* old_data = nullptr;
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
queue
Node 1
<- HEAD
<- TAIL
Thread 1 ‘A’
old_tail TAIL
old_next
new_next 1, Node2
Thread 2 ‘B’
old_tail TAIL
old_next
new_next 1, Node3
Node1
`A`,
0, nullptr
Node2
``,
0. nullptr
Node3
``,
0, nullptr
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
57
Thread 1 Thread 2
push( `A` ) push( `B` )
1
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
2
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
3
else
{
counted_node_ptr old_next = { 0 };
if( old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
4
{
old_next = new_next;
new_next.ptr = new node;
}
set_new_tail( old_tail, old_next );
}
5
counted_node_ptr old_next = { 0 };
if( !old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
{
delete new_next.ptr;
new_next = old_next;
}
set_new_tail( old_tail, new_next );
new_data.release();
}
break;
queue
Node 1
<- HEAD
<- TAIL
Thread 1 ‘A’
old_tail TAIL
old_next
new_next 1, Node2
Thread 2 ‘B’
old_tail TAIL
old_next 0, nullptr
new_next 1, Node3
Node1
`A`,
1, Node3
Node2
``,
0, nullptr
Node3
``,
0, nullptr
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
58
Thread 1 Thread 2
push( `A` ) push( `B` )
1
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
2
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
3
else
{
counted_node_ptr old_next = { 0 };
if( old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
4
{
old_next = new_next;
new_next.ptr = new node;
}
set_new_tail( old_tail, old_next );
}
5
counted_node_ptr old_next = { 0 };
if( !old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
{
delete new_next.ptr;
new_next = old_next;
}
set_new_tail( old_tail, new_next );
new_data.release();
}
break;
queue
Node 1
<- HEAD
Node3 <- TAIL
Thread 1 ‘A’
old_tail TAIL
old_next
new_next 1, Node2
Thread 2 ‘B’
old_tail TAIL
old_next 1, Node3
new_next 1, Node4
Node1
`A`,
1, Node3
Node2
``,
0, nullptr
Node3
``,
0, nullptr
Node4
``,
0, nullptr
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
59
Thread 1 Thread 2
push( `A` ) push( `B` )
1
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
2
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
3
else
{
counted_node_ptr old_next = { 0 };
if( old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
4
{
old_next = new_next;
new_next.ptr = new node;
}
set_new_tail( old_tail, old_next );
}
5
counted_node_ptr old_next = { 0 };
if( !old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
{
delete new_next.ptr;
new_next = old_next;
}
set_new_tail( old_tail, new_next );
new_data.release();
}
break;
queue
Node 1
<- HEAD
Node3 <- TAIL
Thread 1 ‘A’
old_tail TAIL
old_next 0, nullptr
new_next 0, nullptr
Thread 2 ‘B’
old_tail TAIL
old_next
new_next 1, Node4
Node1
`A`,
1, Node3
Node2
``,
0, nullptr
Node3
``,
0, nullptr
Node4
``,
0, nullptr
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
60
Thread 1 Thread 2
push( `A` ) push( `B` )
4
set_new_tail( old_tail, old_next );
}
5
counted_node_ptr old_next = { 0 };
if( !old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
{
delete new_next.ptr;
new_next = old_next;
}
set_new_tail( old_tail, new_next );
new_data.release();
}
break;
6
increase_external_count( tail, old_tail );
T* old_data = nullptr;
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
{
7
counted_node_ptr old_next = { 0 };
if( !old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
{
delete new_next.ptr;
new_next = old_next;
}
set_new_tail( old_tail, new_next );
new_data.release();
}
break;
queue
Node 1
<- HEAD
Node3 <- TAIL
Thread 1 ‘A’
old_tail TAIL
old_next 0, nullptr
new_next 0, nullptr
Thread 2 ‘B’
old_tail TAIL
old_next
new_next 1, Node4
Node1
`A`,
1, Node3
Node2
``,
0, nullptr
Node3
`B`,
0, nullptr
Node4
``,
0, nullptr
C++ Concurrency in Action Study
C++ Korea
Handling multiple threads in push()
61
Thread 1 Thread 2
push( `A` ) push( `B` )
4
set_new_tail( old_tail, old_next );
}
5
counted_node_ptr old_next = { 0 };
if( !old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
{
delete new_next.ptr;
new_next = old_next;
}
set_new_tail( old_tail, new_next );
new_data.release();
}
break;
6
increase_external_count( tail, old_tail );
T* old_data = nullptr;
if( old_tail.ptr->data.compare_exchange_strong(
old_data, new_data.get() ) )
{
7
counted_node_ptr old_next = { 0 };
if( !old_tail.ptr->next.compare_exchange_strong(
old_next, new_next ) )
{
delete new_next.ptr;
new_next = old_next;
}
set_new_tail( old_tail, new_next );
new_data.release();
}
break;
queue
Node 1
<- HEAD
Node3
Node4 <- TAIL
Thread 1 ‘A’
old_tail TAIL
old_next 0, nullptr
new_next 0, nullptr
Thread 2 ‘B’
old_tail TAIL
old_next 0, nullptr
new_next 1, Node4
Node1
`A`,
1, Node3
Node2
``,
0, nullptr
Node3
`B`,
1, Node4
Node4
``,
0, nullptr
C++ Concurrency in Action Study
C++ Korea
Performance Test ( 시나리오 )
62
void test( int aThreadID,
lock_free_queue<std::string> * aLockFreeQueue,
int aCount )
{
for ( int i = 0; i < aCount; i++ )
{
aLockFreeQueue->push( "TEST1234567890" );
}
for ( int i = 0; i < aCount; i++ )
{
aLockFreeQueue->pop();
}
}
C++ Concurrency in Action Study
C++ Korea
Performance Test ( 시나리오 )
63
TIME(1) BSD General Commands Manual TIME(1)
NAME
time -- time command execution
SYNOPSIS
time [-lp] utility
DESCRIPTION
The time utility executes and times utility. After the utility finishes, time writes the
total time elapsed, the time consumed by system overhead, and the time used to execute
utility to the standard error stream. Times are reported in seconds.
DoO@DooSeonui-MacBook-Air ~/Work/Study/Whatever/LockFreeQueue/build master ● time
shell 0.09s user 0.09s system 5% cpu 3.440 total
children 0.11s user 0.20s system 8% cpu 3.440 total
User User Mode 에서 CPU 를 사용한 시간
sysem Kernel Mode 에서 CPU 를 사용한 시간
total 총 CPU 를 사용한 시간
C++ Concurrency in Action Study
C++ Korea
Performance Test ( Test 환경)
64
$ g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Thread model: posix
C++ Concurrency in Action Study
C++ Korea
Performance Test ( 수행시간 )
65
1 4 8 16 32 64
ThreadSafeQueue user 0.72 11.88 23.25 47.08 97.53 211.40
sys 0.04 34.70 72.09 150.95 322.91 723.82
real 0.771 41.083 84.63 174.07 361.09 780
LockFreeQueue user 0.82 11.91 29.05 74.84 201.91 537.76
sys 0.04 0.2 0.4 0.85 5.69 32.26
real 0.86 3.23 7.43 19.249 53.122 155.63
C++ Concurrency in Action Study
C++ Korea
Performance Test ( 수행시간 )
66
0
250
500
750
1000
1 4 8 16 32 64 1 4 8 16 32 64
값축
제목
sys user
ThreadSafeQueue LockFreeQueue
C++ Concurrency in Action Study
C++ Korea
Performance Test ( CPU 사용량 )
67
1 4 8 16 32 64
ThreadSafeQueue 99% 113% 112% 113% 116% 119%
LockFreeQueue 99% 374% 394% 393% 390% 365%
C++ Concurrency in Action Study
C++ Korea
Performance Test ( CPU 사용량 )
68
0%
100%
200%
300%
400%
500%
1 4 8 16 32 64
값축
제목
ThreadSafeQueue LockFreeQueue
C++ Concurrency in Action Study
C++ Korea
Performance Test ( Test 환경)
69
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-
languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix -
-with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --
disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-
home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-
ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-
linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
C++ Concurrency in Action Study
C++ Korea
Performance Test ( 수행시간 )
70
1 4 8 16 32 64
ThreadSafeQueue user 0.98 7.53 12.85 26.29 52.47 112.23
sys 0.03 6.52 14.01 24.53 50.38 111.34
real 1.013 4.727 8.99 18.80 39.62 77.57
LockFreeQueue user 0.52 7.08 15.52 39.81 82.67 380.45
sys 0.06 0.27 1.17 2.6 5.32 11.61
real 0.538 2.291 5.87 16.07 35.83 129.21
LockFreeQueue2 user 0.58 9.73 18.97 26.69 50.52 103.25
sys 0.06 0.34 1.51 2.90 5.88 13.70
real 0.644 3.031 6.681 12.813 26.40 44.34
C++ Concurrency in Action Study
C++ Korea
Performance Test ( 수행시간 )
71
0
100
200
300
400
500
1 4 8 16 32 64 1 4 8 16 32 64 1 4 8 16 32 64
값축
제목
user sys
ThreadSafeQueue LockFreeQueue LockFreeQueue2
C++ Concurrency in Action Study
C++ Korea
Performance Test ( CPU 사용량 )
72
1 4 8 16 32 64
ThreadSafeQueue 99% 297% 298% 270% 259% 288%
LockFreeQueue 99% 320% 284% 263% 248% 303%
LockFreeQueue2 99% 332% 306% 254% 213% 263%
C++ Concurrency in Action Study
C++ Korea
Performance Test ( CPU 사용량 )
73
0%
100%
200%
300%
400%
1 4 8 16 32 64
값축
제목
ThreadSafeQueue LockFreeQueue LockFreeQueue2
C++ Concurrency in Action Study
C++ Korea
Guidelines for writing
lock free data structure
C++ Concurrency in Action Study
C++ Korea
use std::memory_order_seq_cst for prototyping
75
C++ Concurrency in Action Study
C++ Korea
use a lock-free memory reclamation scheme
76
C++ Concurrency in Action Study
C++ Korea
watch out for ABA Problem
77
C++ Concurrency in Action Study
C++ Korea
watch out for ABA Problem
78
From The Art of Multiprocessor Programming
C++ Concurrency in Action Study
C++ Korea
watch out for ABA Problem
79
From The Art of Multiprocessor Programming
C++ Concurrency in Action Study
C++ Korea
watch out for ABA Problem
80
Thread1 Thread2 Thread3 Thread4
1 POP()
2
POP()
3
PUSH()
4
PUSH()
5
POP()
7
head.CAS( A, B )
Queue
A Head
B Tail
Free
Memory List
C
D
E
C++ Concurrency in Action Study
C++ Korea
watch out for ABA Problem
81
Thread1 Thread2 Thread3 Thread4
1 POP()
2
POP()
-> free A
3
PUSH()
4
PUSH()
5
POP()
7
head.CAS( A, B )
Queue
B
Head
Tail
Free
Memory List
A
C
D
E
C++ Concurrency in Action Study
C++ Korea
watch out for ABA Problem
82
Thread1 Thread2 Thread3 Thread4
1 POP()
2
POP()
-> free A
3
PUSH()
-> new A
4
PUSH()
5
POP()
7
head.CAS( A, B )
Queue
B Head
A Tail
Free
Memory List
C
D
E
C++ Concurrency in Action Study
C++ Korea
watch out for ABA Problem
83
Thread1 Thread2 Thread3 Thread4
1 POP()
2
POP()
-> free A
3
PUSH()
-> new A
4
PUSH()
-> new C
5
POP()
7
head.CAS( A, B )
Queue
B Head
A
C Tail
Free
Memory List
D
E
C++ Concurrency in Action Study
C++ Korea
watch out for ABA Problem
84
Thread1 Thread2 Thread3 Thread4
1 POP()
2
POP()
-> free A
3
PUSH()
-> new A
4
PUSH()
-> new C
5
POP()
-> free B
7
head.CAS( A, B )
Queue
A
C Tail
Free
Memory List
B Head
D
E
C++ Concurrency in Action Study
C++ Korea
watch out for ABA Problem
85
C++ Concurrency in Action Study
C++ Korea
identify busy-wait loops and help the other thread-
safe
86
C++ Concurrency in Action Study
C++ Korea
mutex vs spin lock
87
C++ Concurrency in Action Study
C++ Korea
system call
88
C++ Concurrency in Action Study
C++ Korea
SUMMARY
C++ Concurrency in Action Study
C++ Korea
Summary
90
C++ Concurrency in Action Study
C++ Korea
앞으로는…?
91
C++ Concurrency in Action Study
C++ Korea
Conclusion
92
C++ Concurrency in Action Study
C++ Korea
Conclusion
93
C++ Concurrency in Action Study
C++ Korea
Q & A
C++ Concurrency in Action Study
C++ Korea
reference
https://forums.manning.com/
http://en.cppreference.com/
intel.com
http://libcds.sourceforge.net
https://www.threadingbuildingblocks.org
https://www.threadingbuildingblocks.org/intel-tbb-tutorial
http://www.boost.org/doc/libs/1_60_0/doc/html/lockfree.html
95

More Related Content

What's hot

Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Platonov Sergey
 
FPGA Implementation of A New Chien Search Block for Reed-Solomon Codes RS (25...
FPGA Implementation of A New Chien Search Block for Reed-Solomon Codes RS (25...FPGA Implementation of A New Chien Search Block for Reed-Solomon Codes RS (25...
FPGA Implementation of A New Chien Search Block for Reed-Solomon Codes RS (25...IJERA Editor
 
Data structures cs301 power point slides lecture 03
Data structures   cs301 power point slides lecture 03Data structures   cs301 power point slides lecture 03
Data structures cs301 power point slides lecture 03Nasir Mehmood
 
19 algorithms-and-complexity-110627100203-phpapp02
19 algorithms-and-complexity-110627100203-phpapp0219 algorithms-and-complexity-110627100203-phpapp02
19 algorithms-and-complexity-110627100203-phpapp02Muhammad Aslam
 
Gate Computer Science Solved Paper 2007
Gate Computer Science Solved Paper 2007 Gate Computer Science Solved Paper 2007
Gate Computer Science Solved Paper 2007 Rohit Garg
 
computer notes - Data Structures - 3
computer notes - Data Structures - 3computer notes - Data Structures - 3
computer notes - Data Structures - 3ecomputernotes
 
An optimal and progressive algorithm for skyline queries slide
An optimal and progressive algorithm for skyline queries slideAn optimal and progressive algorithm for skyline queries slide
An optimal and progressive algorithm for skyline queries slideWooSung Choi
 
zkStudyClub: PLONKUP & Reinforced Concrete [Luke Pearson, Joshua Fitzgerald, ...
zkStudyClub: PLONKUP & Reinforced Concrete [Luke Pearson, Joshua Fitzgerald, ...zkStudyClub: PLONKUP & Reinforced Concrete [Luke Pearson, Joshua Fitzgerald, ...
zkStudyClub: PLONKUP & Reinforced Concrete [Luke Pearson, Joshua Fitzgerald, ...Alex Pruden
 
Datastructure tree
Datastructure treeDatastructure tree
Datastructure treerantd
 
[系列活動] Data exploration with modern R
[系列活動] Data exploration with modern R[系列活動] Data exploration with modern R
[系列活動] Data exploration with modern R台灣資料科學年會
 
PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...Andrey Karpov
 
ZK Study Club: Sumcheck Arguments and Their Applications
ZK Study Club: Sumcheck Arguments and Their ApplicationsZK Study Club: Sumcheck Arguments and Their Applications
ZK Study Club: Sumcheck Arguments and Their ApplicationsAlex Pruden
 
とある断片の超動的言語
とある断片の超動的言語とある断片の超動的言語
とある断片の超動的言語Kiyotaka Oku
 
쉽게 설명하는 GAN (What is this? Gum? It's GAN.)
쉽게 설명하는 GAN (What is this? Gum? It's GAN.)쉽게 설명하는 GAN (What is this? Gum? It's GAN.)
쉽게 설명하는 GAN (What is this? Gum? It's GAN.)Hansol Kang
 
zkStudy Club: Subquadratic SNARGs in the Random Oracle Model
zkStudy Club: Subquadratic SNARGs in the Random Oracle ModelzkStudy Club: Subquadratic SNARGs in the Random Oracle Model
zkStudy Club: Subquadratic SNARGs in the Random Oracle ModelAlex Pruden
 

What's hot (20)

Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”Rainer Grimm, “Functional Programming in C++11”
Rainer Grimm, “Functional Programming in C++11”
 
FPGA Implementation of A New Chien Search Block for Reed-Solomon Codes RS (25...
FPGA Implementation of A New Chien Search Block for Reed-Solomon Codes RS (25...FPGA Implementation of A New Chien Search Block for Reed-Solomon Codes RS (25...
FPGA Implementation of A New Chien Search Block for Reed-Solomon Codes RS (25...
 
Data structures cs301 power point slides lecture 03
Data structures   cs301 power point slides lecture 03Data structures   cs301 power point slides lecture 03
Data structures cs301 power point slides lecture 03
 
19 algorithms-and-complexity-110627100203-phpapp02
19 algorithms-and-complexity-110627100203-phpapp0219 algorithms-and-complexity-110627100203-phpapp02
19 algorithms-and-complexity-110627100203-phpapp02
 
Gate Computer Science Solved Paper 2007
Gate Computer Science Solved Paper 2007 Gate Computer Science Solved Paper 2007
Gate Computer Science Solved Paper 2007
 
computer notes - Data Structures - 3
computer notes - Data Structures - 3computer notes - Data Structures - 3
computer notes - Data Structures - 3
 
An optimal and progressive algorithm for skyline queries slide
An optimal and progressive algorithm for skyline queries slideAn optimal and progressive algorithm for skyline queries slide
An optimal and progressive algorithm for skyline queries slide
 
Gate-Cs 2006
Gate-Cs 2006Gate-Cs 2006
Gate-Cs 2006
 
zkStudyClub: PLONKUP & Reinforced Concrete [Luke Pearson, Joshua Fitzgerald, ...
zkStudyClub: PLONKUP & Reinforced Concrete [Luke Pearson, Joshua Fitzgerald, ...zkStudyClub: PLONKUP & Reinforced Concrete [Luke Pearson, Joshua Fitzgerald, ...
zkStudyClub: PLONKUP & Reinforced Concrete [Luke Pearson, Joshua Fitzgerald, ...
 
Datastructure tree
Datastructure treeDatastructure tree
Datastructure tree
 
[系列活動] Data exploration with modern R
[系列活動] Data exploration with modern R[系列活動] Data exploration with modern R
[系列活動] Data exploration with modern R
 
Mutation @ Spotify
Mutation @ Spotify Mutation @ Spotify
Mutation @ Spotify
 
Gate-Cs 2009
Gate-Cs 2009Gate-Cs 2009
Gate-Cs 2009
 
PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...
 
ZK Study Club: Sumcheck Arguments and Their Applications
ZK Study Club: Sumcheck Arguments and Their ApplicationsZK Study Club: Sumcheck Arguments and Their Applications
ZK Study Club: Sumcheck Arguments and Their Applications
 
とある断片の超動的言語
とある断片の超動的言語とある断片の超動的言語
とある断片の超動的言語
 
쉽게 설명하는 GAN (What is this? Gum? It's GAN.)
쉽게 설명하는 GAN (What is this? Gum? It's GAN.)쉽게 설명하는 GAN (What is this? Gum? It's GAN.)
쉽게 설명하는 GAN (What is this? Gum? It's GAN.)
 
Skyline queries
Skyline queriesSkyline queries
Skyline queries
 
1st Semester M Tech Computer Science and Engg (Dec-2013) Question Papers
1st Semester M Tech Computer Science and Engg  (Dec-2013) Question Papers 1st Semester M Tech Computer Science and Engg  (Dec-2013) Question Papers
1st Semester M Tech Computer Science and Engg (Dec-2013) Question Papers
 
zkStudy Club: Subquadratic SNARGs in the Random Oracle Model
zkStudy Club: Subquadratic SNARGs in the Random Oracle ModelzkStudy Club: Subquadratic SNARGs in the Random Oracle Model
zkStudy Club: Subquadratic SNARGs in the Random Oracle Model
 

Similar to CppConcurrencyInAction - Chapter07

queuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbb
queuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbbqueuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbb
queuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbbRAtna29
 
ESL Anyone?
ESL Anyone? ESL Anyone?
ESL Anyone? DVClub
 
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrainsit-people
 
Ds lab manual by s.k.rath
Ds lab manual by s.k.rathDs lab manual by s.k.rath
Ds lab manual by s.k.rathSANTOSH RATH
 
Consider this code using the ArrayBag of Section 5.2 and the Locat.docx
Consider this code using the ArrayBag of Section 5.2 and the Locat.docxConsider this code using the ArrayBag of Section 5.2 and the Locat.docx
Consider this code using the ArrayBag of Section 5.2 and the Locat.docxmaxinesmith73660
 
Python 如何執行
Python 如何執行Python 如何執行
Python 如何執行kao kuo-tung
 
Lock free algorithms
Lock free algorithmsLock free algorithms
Lock free algorithmsPan Ip
 
Lecture 9_Classes.pptx
Lecture 9_Classes.pptxLecture 9_Classes.pptx
Lecture 9_Classes.pptxNelyJay
 
Redo midterm
Redo midtermRedo midterm
Redo midtermIIUM
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimizationg3_nittala
 
cs201-list-stack-queue.ppt
cs201-list-stack-queue.pptcs201-list-stack-queue.ppt
cs201-list-stack-queue.pptRahulYadav738822
 
PostgreSQL Open SV 2018
PostgreSQL Open SV 2018PostgreSQL Open SV 2018
PostgreSQL Open SV 2018artgillespie
 

Similar to CppConcurrencyInAction - Chapter07 (20)

01_intro-cpp.ppt
01_intro-cpp.ppt01_intro-cpp.ppt
01_intro-cpp.ppt
 
01_intro-cpp.ppt
01_intro-cpp.ppt01_intro-cpp.ppt
01_intro-cpp.ppt
 
3.01.Lists.pptx
3.01.Lists.pptx3.01.Lists.pptx
3.01.Lists.pptx
 
queuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbb
queuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbbqueuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbb
queuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbb
 
ESL Anyone?
ESL Anyone? ESL Anyone?
ESL Anyone?
 
Data Structure and Algorithm
Data Structure and AlgorithmData Structure and Algorithm
Data Structure and Algorithm
 
Lab 1
Lab 1Lab 1
Lab 1
 
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
 
Ds lab manual by s.k.rath
Ds lab manual by s.k.rathDs lab manual by s.k.rath
Ds lab manual by s.k.rath
 
Consider this code using the ArrayBag of Section 5.2 and the Locat.docx
Consider this code using the ArrayBag of Section 5.2 and the Locat.docxConsider this code using the ArrayBag of Section 5.2 and the Locat.docx
Consider this code using the ArrayBag of Section 5.2 and the Locat.docx
 
Python 如何執行
Python 如何執行Python 如何執行
Python 如何執行
 
2 b queues
2 b queues2 b queues
2 b queues
 
02 stackqueue
02 stackqueue02 stackqueue
02 stackqueue
 
Lock free algorithms
Lock free algorithmsLock free algorithms
Lock free algorithms
 
Lecture 9_Classes.pptx
Lecture 9_Classes.pptxLecture 9_Classes.pptx
Lecture 9_Classes.pptx
 
Redo midterm
Redo midtermRedo midterm
Redo midterm
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimization
 
STLStack.pdf
STLStack.pdfSTLStack.pdf
STLStack.pdf
 
cs201-list-stack-queue.ppt
cs201-list-stack-queue.pptcs201-list-stack-queue.ppt
cs201-list-stack-queue.ppt
 
PostgreSQL Open SV 2018
PostgreSQL Open SV 2018PostgreSQL Open SV 2018
PostgreSQL Open SV 2018
 

Recently uploaded

(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Dr.Costas Sachpazis
 
SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )Tsuyoshi Horigome
 
Artificial-Intelligence-in-Electronics (K).pptx
Artificial-Intelligence-in-Electronics (K).pptxArtificial-Intelligence-in-Electronics (K).pptx
Artificial-Intelligence-in-Electronics (K).pptxbritheesh05
 
HARMONY IN THE HUMAN BEING - Unit-II UHV-2
HARMONY IN THE HUMAN BEING - Unit-II UHV-2HARMONY IN THE HUMAN BEING - Unit-II UHV-2
HARMONY IN THE HUMAN BEING - Unit-II UHV-2RajaP95
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile servicerehmti665
 
Heart Disease Prediction using machine learning.pptx
Heart Disease Prediction using machine learning.pptxHeart Disease Prediction using machine learning.pptx
Heart Disease Prediction using machine learning.pptxPoojaBan
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escortsranjana rawat
 
GDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentationGDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentationGDSCAESB
 
Call Girls Narol 7397865700 Independent Call Girls
Call Girls Narol 7397865700 Independent Call GirlsCall Girls Narol 7397865700 Independent Call Girls
Call Girls Narol 7397865700 Independent Call Girlsssuser7cb4ff
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxJoão Esperancinha
 
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionSachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionDr.Costas Sachpazis
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxpurnimasatapathy1234
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130Suhani Kapoor
 
Application of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptxApplication of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptx959SahilShah
 
IVE Industry Focused Event - Defence Sector 2024
IVE Industry Focused Event - Defence Sector 2024IVE Industry Focused Event - Defence Sector 2024
IVE Industry Focused Event - Defence Sector 2024Mark Billinghurst
 
Current Transformer Drawing and GTP for MSETCL
Current Transformer Drawing and GTP for MSETCLCurrent Transformer Drawing and GTP for MSETCL
Current Transformer Drawing and GTP for MSETCLDeelipZope
 
Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.eptoze12
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...Soham Mondal
 

Recently uploaded (20)

(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
 
SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )SPICE PARK APR2024 ( 6,793 SPICE Models )
SPICE PARK APR2024 ( 6,793 SPICE Models )
 
Artificial-Intelligence-in-Electronics (K).pptx
Artificial-Intelligence-in-Electronics (K).pptxArtificial-Intelligence-in-Electronics (K).pptx
Artificial-Intelligence-in-Electronics (K).pptx
 
HARMONY IN THE HUMAN BEING - Unit-II UHV-2
HARMONY IN THE HUMAN BEING - Unit-II UHV-2HARMONY IN THE HUMAN BEING - Unit-II UHV-2
HARMONY IN THE HUMAN BEING - Unit-II UHV-2
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile service
 
Heart Disease Prediction using machine learning.pptx
Heart Disease Prediction using machine learning.pptxHeart Disease Prediction using machine learning.pptx
Heart Disease Prediction using machine learning.pptx
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
 
GDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentationGDSC ASEB Gen AI study jams presentation
GDSC ASEB Gen AI study jams presentation
 
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
young call girls in Rajiv Chowk🔝 9953056974 🔝 Delhi escort Service
 
Call Girls Narol 7397865700 Independent Call Girls
Call Girls Narol 7397865700 Independent Call GirlsCall Girls Narol 7397865700 Independent Call Girls
Call Girls Narol 7397865700 Independent Call Girls
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
 
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionSachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptx
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
 
Application of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptxApplication of Residue Theorem to evaluate real integrations.pptx
Application of Residue Theorem to evaluate real integrations.pptx
 
IVE Industry Focused Event - Defence Sector 2024
IVE Industry Focused Event - Defence Sector 2024IVE Industry Focused Event - Defence Sector 2024
IVE Industry Focused Event - Defence Sector 2024
 
Current Transformer Drawing and GTP for MSETCL
Current Transformer Drawing and GTP for MSETCLCurrent Transformer Drawing and GTP for MSETCL
Current Transformer Drawing and GTP for MSETCL
 
Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.
 
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
OSVC_Meta-Data based Simulation Automation to overcome Verification Challenge...
 

CppConcurrencyInAction - Chapter07

  • 1. C++ Concurrency in Action Study C++ Korea C++ Korea C++ Concurrency in Action Study C++ Korea 박 동하 (luncliff@gmail.com) C++ Korea 최두선 ( returns@lycos.co.kr )
  • 2. C++ Concurrency in Action Study C++ Korea Definition and consequences
  • 3. C++ Concurrency in Action Study C++ Korea Blocking 3
  • 4. C++ Concurrency in Action Study C++ Korea non-Blocking 4
  • 5. C++ Concurrency in Action Study C++ Korea blocking, non-blocking ?? sync, async 5
  • 6. C++ Concurrency in Action Study C++ Korea Implementation of a spin-lock mutex using std::atomic_flag 6
  • 7. C++ Concurrency in Action Study C++ Korea Lock-free Data Structures 7
  • 8. C++ Concurrency in Action Study C++ Korea Lock-free Data Structures 8
  • 9. C++ Concurrency in Action Study C++ Korea wait-free data structures 9
  • 10. C++ Concurrency in Action Study C++ Korea The pros and cons of lock-free data stucture 10
  • 11. C++ Concurrency in Action Study C++ Korea live lock 11
  • 12. C++ Concurrency in Action Study C++ Korea Definitions and Consequences 12
  • 13. C++ Concurrency in Action Study C++ Korea Writing a thread-safe stack without locks
  • 14. C++ Concurrency in Action Study C++ Korea Writing a thread-safe queue without locks
  • 15. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 15
  • 16. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 16
  • 17. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 17
  • 18. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 18
  • 19. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 19
  • 20. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 20
  • 21. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 21 Thread 1 Thread 2 push( ‘A’ ); push( ‘B’ ); 1 std::shared_ptr<T> new_data( std::make_shared<T>( new_value ) ); 2 node* p = new node; 3 node* const old_tail = tail.load(); 4 std::shared_ptr<T> new_data( std::make_shared<T>( new_value ) ); 5 node* p = new node; 6 node* const old_tail = tail.load(); 7 old_tail->data.swap( new_data ); 8 old_tail->next = p; 9 tail.store( p ); 10 old_tail->data.swap( new_data ); 11 old_tail->next = p; 12 tail.store( p ); queue Node <- HEAD <- TAIL Thread 1 new_data `A` p new node1 old_tail Node Thread 2 new_data p old_tail
  • 22. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 22 Thread 1 Thread 2 push( ‘A’ ); push( ‘B’ ); 1 std::shared_ptr<T> new_data( std::make_shared<T>( new_value ) ); 2 node* p = new node; 3 node* const old_tail = tail.load(); 4 std::shared_ptr<T> new_data( std::make_shared<T>( new_value ) ); 5 node* p = new node; 6 node* const old_tail = tail.load(); 7 old_tail->data.swap( new_data ); 8 old_tail->next = p; 9 tail.store( p ); 10 old_tail->data.swap( new_data ); 11 old_tail->next = p; 12 tail.store( p ); queue Node <- HEAD <- TAIL Thread 1 new_data `A` p new node1 old_tail Node Thread 2 new_data `B` p new node2 old_tail Node
  • 23. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 23 Thread 1 Thread 2 push( ‘A’ ); push( ‘B’ ); 1 std::shared_ptr<T> new_data( std::make_shared<T>( new_value ) ); 2 node* p = new node; 3 node* const old_tail = tail.load(); 4 std::shared_ptr<T> new_data( std::make_shared<T>( new_value ) ); 5 node* p = new node; 6 node* const old_tail = tail.load(); 7 old_tail->data.swap( new_data ); 8 old_tail->next = p; 9 tail.store( p ); 10 old_tail->data.swap( new_data ); 11 old_tail->next = p; 12 tail.store( p ); queue Node ’A’ <- HEAD new node1 <- TAIL Thread1 Thread 1 new_data `A` p new node1 old_tail Node Thread 2 new_data `B` p new node2 old_tail Node
  • 24. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 24 Thread 1 Thread 2 push( ‘A’ ); push( ‘B’ ); 1 std::shared_ptr<T> new_data( std::make_shared<T>( new_value ) ); 2 node* p = new node; 3 node* const old_tail = tail.load(); 4 std::shared_ptr<T> new_data( std::make_shared<T>( new_value ) ); 5 node* p = new node; 6 node* const old_tail = tail.load(); 7 old_tail->data.swap( new_data ); 8 old_tail->next = p; 9 tail.store( p ); 10 old_tail->data.swap( new_data ); 11 old_tail->next = p; 12 tail.store( p ); queue Node ’B’ <- HEAD New Node2 <- TAIL Thread2 new node1 Thread1 Thread 1 new_data `A` p new node1 old_tail Node Thread 2 new_data `B` p new node2 old_tail Node
  • 25. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 25
  • 26. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 26 Thread 1 Thread 2 pop() pop() node* old_head = pop_head(); node* old_head = pop_head(); 1 node* pop_head() { node* const old_head=head.load(); if( old_head == tail.load() ) { return nullptr } 2 node* pop_head() { node* const old_head=head.load(); if( old_head == tail.load() ) { return nullptr } 3 head.store( old_head->next ); return old_head; } 4 head.store( old_head->next ); return old_head; } queue Node ’A’ <- HEAD Node2 <- TAIL Thread 1 old_head Node Thread 2 old_head
  • 27. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 27 Thread 1 Thread 2 pop() pop() node* old_head = pop_head(); node* old_head = pop_head(); 1 node* pop_head() { node* const old_head=head.load(); if( old_head == tail.load() ) { return nullptr } 2 node* pop_head() { node* const old_head=head.load(); if( old_head == tail.load() ) { return nullptr } 3 head.store( old_head->next ); return old_head; } 4 head.store( old_head->next ); return old_head; } queue Node ’A’ <- HEAD Node2 <- TAIL Thread 1 old_head Node Thread 2 old_head Node
  • 28. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 28 Thread 1 Thread 2 pop() pop() node* old_head = pop_head(); node* old_head = pop_head(); 1 node* pop_head() { node* const old_head=head.load(); if( old_head == tail.load() ) { return nullptr } 2 node* pop_head() { node* const old_head=head.load(); if( old_head == tail.load() ) { return nullptr } 3 head.store( old_head->next ); return old_head; } 4 head.store( old_head->next ); return old_head; } queue Node2 <- HEAD <- TAIL Node ’A’ Thread 1 old_head Node ‘A’ Thread 2 old_head Node ‘A’
  • 29. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 29 Thread 1 Thread 2 pop() pop() node* old_head = pop_head(); node* old_head = pop_head(); 1 node* pop_head() { node* const old_head=head.load(); if( old_head == tail.load() ) { return nullptr } 2 node* pop_head() { node* const old_head=head.load(); if( old_head == tail.load() ) { return nullptr } 3 head.store( old_head->next ); return old_head; } 4 head.store( old_head->next ); return old_head; } queue Node2 <- HEAD <- TAIL Node ’A’ Thread 1 old_head Node ‘A’ Thread 2 old_head Node ‘A’
  • 30. C++ Concurrency in Action Study C++ Korea A single-producer, single-consumer lock free queue 30 Thread 1 Thread 2 pop() pop() node* old_head = pop_head(); 1 node* old_head = pop_head(); 2 if( !old_head ) { return std::shared_ptr<T>(); } std::shared_ptr<T> const res ( old_head->data ); delete old_head; return res; 3 if( !old_head ) { return std::shared_ptr<T>(); } std::shared_ptr<T> const res ( old_head->data ); delete old_head; return res; queue Node2 <- HEAD <- TAIL Node ’A’ Thread 1 old_head Node ‘A’ res Node ‘A’ Thread 2 old_head Node ‘A’ res Node ‘A’
  • 31. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 31
  • 32. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 32
  • 33. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 33
  • 34. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 34
  • 35. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 35
  • 36. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 36 Thread 1 Thread 2 push() pop() std::unique_ptr<T> new_data(new T(new_value)); counted_node_ptr new_next; new_next.ptr = new node; new_next.external_count = 1; for(;;) { node* const old_tail = tail.load(); T* old_data = nullptr; if( old_tail->data.compare_exchange_strong( old_data, new_data.get() ) ) { 1 node* old_head = pop_head(); if( !old_head ) { return std::shared_ptr<T>(); } std::shared_ptr<T> const res( old_head->data ); delete old_head; return res; 2 old_tail->next = new_next; tail.store( new_next.ptr ); new_data.release(); break; } } queue Node <- HEAD <- TAIL Thread 1 new_data old_tail Thread 2 old_head
  • 37. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 37 Thread 1 Thread 2 push() pop() std::unique_ptr<T> new_data(new T(new_value)); counted_node_ptr new_next; new_next.ptr = new node; new_next.external_count = 1; for(;;) { node* const old_tail = tail.load(); T* old_data = nullptr; if( old_tail->data.compare_exchange_strong( old_data, new_data.get() ) ) { 1 node* old_head = pop_head(); if( !old_head ) { return std::shared_ptr<T>(); } std::shared_ptr<T> const res( old_head->data ); delete old_head; return res; 2 old_tail->next = new_next; tail.store( new_next.ptr ); new_data.release(); break; } } queue Node ‘A’ <- HEAD <- TAIL Thread 1 new_data ‘A’ old_tail Node Thread 2 old_head
  • 38. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 38 Thread 1 Thread 2 push() pop() std::unique_ptr<T> new_data(new T(new_value)); counted_node_ptr new_next; new_next.ptr = new node; new_next.external_count = 1; for(;;) { node* const old_tail = tail.load(); T* old_data = nullptr; if( old_tail->data.compare_exchange_strong( old_data, new_data.get() ) ) { 1 node* old_head = pop_head(); if( !old_head ) { return std::shared_ptr<T>(); } std::shared_ptr<T> const res( old_head->data ); delete old_head; return res; 2 old_tail->next = new_next; tail.store( new_next.ptr ); new_data.release(); break; } } queue <- HEAD <- TAIL Node ‘A’ Thread 1 new_data ‘A’ old_tail Node Thread 2 old_head Node
  • 39. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 39 Thread 1 Thread 2 push() pop() std::unique_ptr<T> new_data(new T(new_value)); counted_node_ptr new_next; new_next.ptr = new node; new_next.external_count = 1; for(;;) { node* const old_tail = tail.load(); T* old_data = nullptr; if( old_tail->data.compare_exchange_strong( old_data, new_data.get() ) ) { 1 node* old_head = pop_head(); if( !old_head ) { return std::shared_ptr<T>(); } std::shared_ptr<T> const res( old_head->data ); delete old_head; return res; 2 old_tail->next = new_next; tail.store( new_next.ptr ); new_data.release(); break; } } queue <- HEAD <- TAIL Node ‘A’ Thread 1 new_data ‘A’ old_tail Node Thread 2 old_head Node
  • 40. C++ Concurrency in Action Study C++ Korea Implementing push() for a lock free queue 40
  • 41. C++ Concurrency in Action Study C++ Korea Implementing push() for a lock free queue 41
  • 42. C++ Concurrency in Action Study C++ Korea Implementing push() for a lock free queue 42
  • 43. C++ Concurrency in Action Study C++ Korea Implementing push() for a lock free queue 43
  • 44. C++ Concurrency in Action Study C++ Korea Poping a node from lock-free queue 44
  • 45. C++ Concurrency in Action Study C++ Korea Releasing a node reference 45
  • 46. C++ Concurrency in Action Study C++ Korea Obtaining a new reference to a node 46
  • 47. C++ Concurrency in Action Study C++ Korea Freeing an external counter to a node 47
  • 48. C++ Concurrency in Action Study C++ Korea lock free ??? 48
  • 49. C++ Concurrency in Action Study C++ Korea Making The Queue Lock-free By Helping out Another Thread 49
  • 50. C++ Concurrency in Action Study C++ Korea pop() modified to allow helping on push() side 50
  • 51. C++ Concurrency in Action Study C++ Korea pop() modified to allow helping on push() side 51
  • 52. C++ Concurrency in Action Study C++ Korea sample push() with helping for lock-free queue 52
  • 53. C++ Concurrency in Action Study C++ Korea sample push() with helping for lock-free queue 53
  • 54. C++ Concurrency in Action Study C++ Korea sample push() with helping for lock-free queue 54
  • 55. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 55 Thread 1 Thread 2 push( `A` ) push( `B` ) 1 std::unique_ptr<T> new_data( new T( new_value ) ); counted_node_ptr new_next; new_next.ptr = new node; new_next.external_count = 1; counted_node_ptr old_tail = tail.load(); for(;;) { increase_external_count( tail,old_tail ); T* old_data = nullptr; if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) 2 std::unique_ptr<T> new_data( new T( new_value ) ); counted_node_ptr new_next; new_next.ptr = new node; new_next.external_count = 1; counted_node_ptr old_tail = tail.load(); for(;;) { increase_external_count( tail,old_tail ); T* old_data = nullptr; if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) queue Node 1 <- HEAD <- TAIL Thread 1 ‘A’ old_tail TAIL old_next new_next 1, Node2 Thread 2 ‘B’ old_tail old_next new_next Node1 `A`, 0, nullptr Node2 ``, 0, nullptr
  • 56. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 56 Thread 1 Thread 2 push( `A` ) push( `B` ) 1 std::unique_ptr<T> new_data( new T( new_value ) ); counted_node_ptr new_next; new_next.ptr = new node; new_next.external_count = 1; counted_node_ptr old_tail = tail.load(); for(;;) { increase_external_count( tail,old_tail ); T* old_data = nullptr; if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) 2 std::unique_ptr<T> new_data( new T( new_value ) ); counted_node_ptr new_next; new_next.ptr = new node; new_next.external_count = 1; counted_node_ptr old_tail = tail.load(); for(;;) { increase_external_count( tail,old_tail ); T* old_data = nullptr; if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) queue Node 1 <- HEAD <- TAIL Thread 1 ‘A’ old_tail TAIL old_next new_next 1, Node2 Thread 2 ‘B’ old_tail TAIL old_next new_next 1, Node3 Node1 `A`, 0, nullptr Node2 ``, 0. nullptr Node3 ``, 0, nullptr
  • 57. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 57 Thread 1 Thread 2 push( `A` ) push( `B` ) 1 if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) 2 if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) 3 else { counted_node_ptr old_next = { 0 }; if( old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) 4 { old_next = new_next; new_next.ptr = new node; } set_new_tail( old_tail, old_next ); } 5 counted_node_ptr old_next = { 0 }; if( !old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) { delete new_next.ptr; new_next = old_next; } set_new_tail( old_tail, new_next ); new_data.release(); } break; queue Node 1 <- HEAD <- TAIL Thread 1 ‘A’ old_tail TAIL old_next new_next 1, Node2 Thread 2 ‘B’ old_tail TAIL old_next 0, nullptr new_next 1, Node3 Node1 `A`, 1, Node3 Node2 ``, 0, nullptr Node3 ``, 0, nullptr
  • 58. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 58 Thread 1 Thread 2 push( `A` ) push( `B` ) 1 if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) 2 if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) 3 else { counted_node_ptr old_next = { 0 }; if( old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) 4 { old_next = new_next; new_next.ptr = new node; } set_new_tail( old_tail, old_next ); } 5 counted_node_ptr old_next = { 0 }; if( !old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) { delete new_next.ptr; new_next = old_next; } set_new_tail( old_tail, new_next ); new_data.release(); } break; queue Node 1 <- HEAD Node3 <- TAIL Thread 1 ‘A’ old_tail TAIL old_next new_next 1, Node2 Thread 2 ‘B’ old_tail TAIL old_next 1, Node3 new_next 1, Node4 Node1 `A`, 1, Node3 Node2 ``, 0, nullptr Node3 ``, 0, nullptr Node4 ``, 0, nullptr
  • 59. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 59 Thread 1 Thread 2 push( `A` ) push( `B` ) 1 if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) 2 if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) 3 else { counted_node_ptr old_next = { 0 }; if( old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) 4 { old_next = new_next; new_next.ptr = new node; } set_new_tail( old_tail, old_next ); } 5 counted_node_ptr old_next = { 0 }; if( !old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) { delete new_next.ptr; new_next = old_next; } set_new_tail( old_tail, new_next ); new_data.release(); } break; queue Node 1 <- HEAD Node3 <- TAIL Thread 1 ‘A’ old_tail TAIL old_next 0, nullptr new_next 0, nullptr Thread 2 ‘B’ old_tail TAIL old_next new_next 1, Node4 Node1 `A`, 1, Node3 Node2 ``, 0, nullptr Node3 ``, 0, nullptr Node4 ``, 0, nullptr
  • 60. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 60 Thread 1 Thread 2 push( `A` ) push( `B` ) 4 set_new_tail( old_tail, old_next ); } 5 counted_node_ptr old_next = { 0 }; if( !old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) { delete new_next.ptr; new_next = old_next; } set_new_tail( old_tail, new_next ); new_data.release(); } break; 6 increase_external_count( tail, old_tail ); T* old_data = nullptr; if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) { 7 counted_node_ptr old_next = { 0 }; if( !old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) { delete new_next.ptr; new_next = old_next; } set_new_tail( old_tail, new_next ); new_data.release(); } break; queue Node 1 <- HEAD Node3 <- TAIL Thread 1 ‘A’ old_tail TAIL old_next 0, nullptr new_next 0, nullptr Thread 2 ‘B’ old_tail TAIL old_next new_next 1, Node4 Node1 `A`, 1, Node3 Node2 ``, 0, nullptr Node3 `B`, 0, nullptr Node4 ``, 0, nullptr
  • 61. C++ Concurrency in Action Study C++ Korea Handling multiple threads in push() 61 Thread 1 Thread 2 push( `A` ) push( `B` ) 4 set_new_tail( old_tail, old_next ); } 5 counted_node_ptr old_next = { 0 }; if( !old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) { delete new_next.ptr; new_next = old_next; } set_new_tail( old_tail, new_next ); new_data.release(); } break; 6 increase_external_count( tail, old_tail ); T* old_data = nullptr; if( old_tail.ptr->data.compare_exchange_strong( old_data, new_data.get() ) ) { 7 counted_node_ptr old_next = { 0 }; if( !old_tail.ptr->next.compare_exchange_strong( old_next, new_next ) ) { delete new_next.ptr; new_next = old_next; } set_new_tail( old_tail, new_next ); new_data.release(); } break; queue Node 1 <- HEAD Node3 Node4 <- TAIL Thread 1 ‘A’ old_tail TAIL old_next 0, nullptr new_next 0, nullptr Thread 2 ‘B’ old_tail TAIL old_next 0, nullptr new_next 1, Node4 Node1 `A`, 1, Node3 Node2 ``, 0, nullptr Node3 `B`, 1, Node4 Node4 ``, 0, nullptr
  • 62. C++ Concurrency in Action Study C++ Korea Performance Test ( 시나리오 ) 62 void test( int aThreadID, lock_free_queue<std::string> * aLockFreeQueue, int aCount ) { for ( int i = 0; i < aCount; i++ ) { aLockFreeQueue->push( "TEST1234567890" ); } for ( int i = 0; i < aCount; i++ ) { aLockFreeQueue->pop(); } }
  • 63. C++ Concurrency in Action Study C++ Korea Performance Test ( 시나리오 ) 63 TIME(1) BSD General Commands Manual TIME(1) NAME time -- time command execution SYNOPSIS time [-lp] utility DESCRIPTION The time utility executes and times utility. After the utility finishes, time writes the total time elapsed, the time consumed by system overhead, and the time used to execute utility to the standard error stream. Times are reported in seconds. DoO@DooSeonui-MacBook-Air ~/Work/Study/Whatever/LockFreeQueue/build master ● time shell 0.09s user 0.09s system 5% cpu 3.440 total children 0.11s user 0.20s system 8% cpu 3.440 total User User Mode 에서 CPU 를 사용한 시간 sysem Kernel Mode 에서 CPU 를 사용한 시간 total 총 CPU 를 사용한 시간
  • 64. C++ Concurrency in Action Study C++ Korea Performance Test ( Test 환경) 64 $ g++ -v Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 7.0.2 (clang-700.1.81) Target: x86_64-apple-darwin15.3.0 Thread model: posix
  • 65. C++ Concurrency in Action Study C++ Korea Performance Test ( 수행시간 ) 65 1 4 8 16 32 64 ThreadSafeQueue user 0.72 11.88 23.25 47.08 97.53 211.40 sys 0.04 34.70 72.09 150.95 322.91 723.82 real 0.771 41.083 84.63 174.07 361.09 780 LockFreeQueue user 0.82 11.91 29.05 74.84 201.91 537.76 sys 0.04 0.2 0.4 0.85 5.69 32.26 real 0.86 3.23 7.43 19.249 53.122 155.63
  • 66. C++ Concurrency in Action Study C++ Korea Performance Test ( 수행시간 ) 66 0 250 500 750 1000 1 4 8 16 32 64 1 4 8 16 32 64 값축 제목 sys user ThreadSafeQueue LockFreeQueue
  • 67. C++ Concurrency in Action Study C++ Korea Performance Test ( CPU 사용량 ) 67 1 4 8 16 32 64 ThreadSafeQueue 99% 113% 112% 113% 116% 119% LockFreeQueue 99% 374% 394% 393% 390% 365%
  • 68. C++ Concurrency in Action Study C++ Korea Performance Test ( CPU 사용량 ) 68 0% 100% 200% 300% 400% 500% 1 4 8 16 32 64 값축 제목 ThreadSafeQueue LockFreeQueue
  • 69. C++ Concurrency in Action Study C++ Korea Performance Test ( Test 환경) 69 $ g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable- languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix - -with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object -- disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java- home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse- ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64- linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
  • 70. C++ Concurrency in Action Study C++ Korea Performance Test ( 수행시간 ) 70 1 4 8 16 32 64 ThreadSafeQueue user 0.98 7.53 12.85 26.29 52.47 112.23 sys 0.03 6.52 14.01 24.53 50.38 111.34 real 1.013 4.727 8.99 18.80 39.62 77.57 LockFreeQueue user 0.52 7.08 15.52 39.81 82.67 380.45 sys 0.06 0.27 1.17 2.6 5.32 11.61 real 0.538 2.291 5.87 16.07 35.83 129.21 LockFreeQueue2 user 0.58 9.73 18.97 26.69 50.52 103.25 sys 0.06 0.34 1.51 2.90 5.88 13.70 real 0.644 3.031 6.681 12.813 26.40 44.34
  • 71. C++ Concurrency in Action Study C++ Korea Performance Test ( 수행시간 ) 71 0 100 200 300 400 500 1 4 8 16 32 64 1 4 8 16 32 64 1 4 8 16 32 64 값축 제목 user sys ThreadSafeQueue LockFreeQueue LockFreeQueue2
  • 72. C++ Concurrency in Action Study C++ Korea Performance Test ( CPU 사용량 ) 72 1 4 8 16 32 64 ThreadSafeQueue 99% 297% 298% 270% 259% 288% LockFreeQueue 99% 320% 284% 263% 248% 303% LockFreeQueue2 99% 332% 306% 254% 213% 263%
  • 73. C++ Concurrency in Action Study C++ Korea Performance Test ( CPU 사용량 ) 73 0% 100% 200% 300% 400% 1 4 8 16 32 64 값축 제목 ThreadSafeQueue LockFreeQueue LockFreeQueue2
  • 74. C++ Concurrency in Action Study C++ Korea Guidelines for writing lock free data structure
  • 75. C++ Concurrency in Action Study C++ Korea use std::memory_order_seq_cst for prototyping 75
  • 76. C++ Concurrency in Action Study C++ Korea use a lock-free memory reclamation scheme 76
  • 77. C++ Concurrency in Action Study C++ Korea watch out for ABA Problem 77
  • 78. C++ Concurrency in Action Study C++ Korea watch out for ABA Problem 78 From The Art of Multiprocessor Programming
  • 79. C++ Concurrency in Action Study C++ Korea watch out for ABA Problem 79 From The Art of Multiprocessor Programming
  • 80. C++ Concurrency in Action Study C++ Korea watch out for ABA Problem 80 Thread1 Thread2 Thread3 Thread4 1 POP() 2 POP() 3 PUSH() 4 PUSH() 5 POP() 7 head.CAS( A, B ) Queue A Head B Tail Free Memory List C D E
  • 81. C++ Concurrency in Action Study C++ Korea watch out for ABA Problem 81 Thread1 Thread2 Thread3 Thread4 1 POP() 2 POP() -> free A 3 PUSH() 4 PUSH() 5 POP() 7 head.CAS( A, B ) Queue B Head Tail Free Memory List A C D E
  • 82. C++ Concurrency in Action Study C++ Korea watch out for ABA Problem 82 Thread1 Thread2 Thread3 Thread4 1 POP() 2 POP() -> free A 3 PUSH() -> new A 4 PUSH() 5 POP() 7 head.CAS( A, B ) Queue B Head A Tail Free Memory List C D E
  • 83. C++ Concurrency in Action Study C++ Korea watch out for ABA Problem 83 Thread1 Thread2 Thread3 Thread4 1 POP() 2 POP() -> free A 3 PUSH() -> new A 4 PUSH() -> new C 5 POP() 7 head.CAS( A, B ) Queue B Head A C Tail Free Memory List D E
  • 84. C++ Concurrency in Action Study C++ Korea watch out for ABA Problem 84 Thread1 Thread2 Thread3 Thread4 1 POP() 2 POP() -> free A 3 PUSH() -> new A 4 PUSH() -> new C 5 POP() -> free B 7 head.CAS( A, B ) Queue A C Tail Free Memory List B Head D E
  • 85. C++ Concurrency in Action Study C++ Korea watch out for ABA Problem 85
  • 86. C++ Concurrency in Action Study C++ Korea identify busy-wait loops and help the other thread- safe 86
  • 87. C++ Concurrency in Action Study C++ Korea mutex vs spin lock 87
  • 88. C++ Concurrency in Action Study C++ Korea system call 88
  • 89. C++ Concurrency in Action Study C++ Korea SUMMARY
  • 90. C++ Concurrency in Action Study C++ Korea Summary 90
  • 91. C++ Concurrency in Action Study C++ Korea 앞으로는…? 91
  • 92. C++ Concurrency in Action Study C++ Korea Conclusion 92
  • 93. C++ Concurrency in Action Study C++ Korea Conclusion 93
  • 94. C++ Concurrency in Action Study C++ Korea Q & A
  • 95. C++ Concurrency in Action Study C++ Korea reference https://forums.manning.com/ http://en.cppreference.com/ intel.com http://libcds.sourceforge.net https://www.threadingbuildingblocks.org https://www.threadingbuildingblocks.org/intel-tbb-tutorial http://www.boost.org/doc/libs/1_60_0/doc/html/lockfree.html 95