SlideShare a Scribd company logo
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 03
Nasir Mehmood
 
19 algorithms-and-complexity-110627100203-phpapp02
19 algorithms-and-complexity-110627100203-phpapp0219 algorithms-and-complexity-110627100203-phpapp02
19 algorithms-and-complexity-110627100203-phpapp02
Muhammad 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 - 3
ecomputernotes
 
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
WooSung Choi
 
Gate-Cs 2006
Gate-Cs 2006Gate-Cs 2006
Gate-Cs 2006
Ravi Rajput
 
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 tree
rantd
 
[系列活動] 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
STAMP Project
 
Gate-Cs 2009
Gate-Cs 2009Gate-Cs 2009
Gate-Cs 2009
Ravi Rajput
 
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 Applications
Alex 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
 
Skyline queries
Skyline queriesSkyline queries
Skyline queries
Victor Torras
 
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
BGS Institute of Technology, Adichunchanagiri University (ACU)
 
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
Alex 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

01_intro-cpp.ppt
01_intro-cpp.ppt01_intro-cpp.ppt
01_intro-cpp.ppt
SWETHAABIRAMIM
 
01_intro-cpp.ppt
01_intro-cpp.ppt01_intro-cpp.ppt
01_intro-cpp.ppt
DrBashirMSaad
 
3.01.Lists.pptx
3.01.Lists.pptx3.01.Lists.pptx
3.01.Lists.pptx
SURESHM22PHD10013
 
queuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbb
queuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbbqueuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbb
queuesArrays.ppt bbbbbbbbbbbbbbbbbbbbbbbbbb
RAtna29
 
ESL Anyone?
ESL Anyone? ESL Anyone?
ESL Anyone?
DVClub
 
Data Structure and Algorithm
Data Structure and AlgorithmData Structure and Algorithm
Data Structure and Algorithm
PRIYA DARSHINI A/P VEJAN
 
Lab 1
Lab 1Lab 1
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
«Отладка в Python 3.6: Быстрее, Выше, Сильнее» Елизавета Шашкова, JetBrains
it-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.rath
SANTOSH 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
maxinesmith73660
 
Python 如何執行
Python 如何執行Python 如何執行
Python 如何執行
kao kuo-tung
 
2 b queues
2 b queues2 b queues
2 b queues
Nguync91368
 
02 stackqueue
02 stackqueue02 stackqueue
02 stackqueue
Chandan Kumar
 
Lock free algorithms
Lock free algorithmsLock free algorithms
Lock free algorithms
Pan Ip
 
Lecture 9_Classes.pptx
Lecture 9_Classes.pptxLecture 9_Classes.pptx
Lecture 9_Classes.pptx
NelyJay
 
Redo midterm
Redo midtermRedo midterm
Redo midterm
IIUM
 
Profiling and optimization
Profiling and optimizationProfiling and optimization
Profiling and optimization
g3_nittala
 
STLStack.pdf
STLStack.pdfSTLStack.pdf
STLStack.pdf
rajaratna4
 
cs201-list-stack-queue.ppt
cs201-list-stack-queue.pptcs201-list-stack-queue.ppt
cs201-list-stack-queue.ppt
RahulYadav738822
 
PostgreSQL Open SV 2018
PostgreSQL Open SV 2018PostgreSQL Open SV 2018
PostgreSQL Open SV 2018
artgillespie
 

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

Engine Lubrication performance System.pdf
Engine Lubrication performance System.pdfEngine Lubrication performance System.pdf
Engine Lubrication performance System.pdf
mamamaam477
 
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
Yasser Mahgoub
 
Optimizing Gradle Builds - Gradle DPE Tour Berlin 2024
Optimizing Gradle Builds - Gradle DPE Tour Berlin 2024Optimizing Gradle Builds - Gradle DPE Tour Berlin 2024
Optimizing Gradle Builds - Gradle DPE Tour Berlin 2024
Sinan KOZAK
 
ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024
Rahul
 
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECTCHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
jpsjournal1
 
Literature Review Basics and Understanding Reference Management.pptx
Literature Review Basics and Understanding Reference Management.pptxLiterature Review Basics and Understanding Reference Management.pptx
Literature Review Basics and Understanding Reference Management.pptx
Dr Ramhari Poudyal
 
22CYT12-Unit-V-E Waste and its Management.ppt
22CYT12-Unit-V-E Waste and its Management.ppt22CYT12-Unit-V-E Waste and its Management.ppt
22CYT12-Unit-V-E Waste and its Management.ppt
KrishnaveniKrishnara1
 
Comparative analysis between traditional aquaponics and reconstructed aquapon...
Comparative analysis between traditional aquaponics and reconstructed aquapon...Comparative analysis between traditional aquaponics and reconstructed aquapon...
Comparative analysis between traditional aquaponics and reconstructed aquapon...
bijceesjournal
 
132/33KV substation case study Presentation
132/33KV substation case study Presentation132/33KV substation case study Presentation
132/33KV substation case study Presentation
kandramariana6
 
Understanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine LearningUnderstanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine Learning
SUTEJAS
 
BRAIN TUMOR DETECTION for seminar ppt.pdf
BRAIN TUMOR DETECTION for seminar ppt.pdfBRAIN TUMOR DETECTION for seminar ppt.pdf
BRAIN TUMOR DETECTION for seminar ppt.pdf
LAXMAREDDY22
 
官方认证美国密歇根州立大学毕业证学位证书原版一模一样
官方认证美国密歇根州立大学毕业证学位证书原版一模一样官方认证美国密歇根州立大学毕业证学位证书原版一模一样
官方认证美国密歇根州立大学毕业证学位证书原版一模一样
171ticu
 
john krisinger-the science and history of the alcoholic beverage.pptx
john krisinger-the science and history of the alcoholic beverage.pptxjohn krisinger-the science and history of the alcoholic beverage.pptx
john krisinger-the science and history of the alcoholic beverage.pptx
Madan Karki
 
The Python for beginners. This is an advance computer language.
The Python for beginners. This is an advance computer language.The Python for beginners. This is an advance computer language.
The Python for beginners. This is an advance computer language.
sachin chaurasia
 
Generative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of contentGenerative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of content
Hitesh Mohapatra
 
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have oneISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
Las Vegas Warehouse
 
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
IJECEIAES
 
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming PipelinesHarnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
Christina Lin
 
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdfBPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
MIGUELANGEL966976
 
Material for memory and display system h
Material for memory and display system hMaterial for memory and display system h
Material for memory and display system h
gowrishankartb2005
 

Recently uploaded (20)

Engine Lubrication performance System.pdf
Engine Lubrication performance System.pdfEngine Lubrication performance System.pdf
Engine Lubrication performance System.pdf
 
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
2008 BUILDING CONSTRUCTION Illustrated - Ching Chapter 02 The Building.pdf
 
Optimizing Gradle Builds - Gradle DPE Tour Berlin 2024
Optimizing Gradle Builds - Gradle DPE Tour Berlin 2024Optimizing Gradle Builds - Gradle DPE Tour Berlin 2024
Optimizing Gradle Builds - Gradle DPE Tour Berlin 2024
 
ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024ACEP Magazine edition 4th launched on 05.06.2024
ACEP Magazine edition 4th launched on 05.06.2024
 
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECTCHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
CHINA’S GEO-ECONOMIC OUTREACH IN CENTRAL ASIAN COUNTRIES AND FUTURE PROSPECT
 
Literature Review Basics and Understanding Reference Management.pptx
Literature Review Basics and Understanding Reference Management.pptxLiterature Review Basics and Understanding Reference Management.pptx
Literature Review Basics and Understanding Reference Management.pptx
 
22CYT12-Unit-V-E Waste and its Management.ppt
22CYT12-Unit-V-E Waste and its Management.ppt22CYT12-Unit-V-E Waste and its Management.ppt
22CYT12-Unit-V-E Waste and its Management.ppt
 
Comparative analysis between traditional aquaponics and reconstructed aquapon...
Comparative analysis between traditional aquaponics and reconstructed aquapon...Comparative analysis between traditional aquaponics and reconstructed aquapon...
Comparative analysis between traditional aquaponics and reconstructed aquapon...
 
132/33KV substation case study Presentation
132/33KV substation case study Presentation132/33KV substation case study Presentation
132/33KV substation case study Presentation
 
Understanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine LearningUnderstanding Inductive Bias in Machine Learning
Understanding Inductive Bias in Machine Learning
 
BRAIN TUMOR DETECTION for seminar ppt.pdf
BRAIN TUMOR DETECTION for seminar ppt.pdfBRAIN TUMOR DETECTION for seminar ppt.pdf
BRAIN TUMOR DETECTION for seminar ppt.pdf
 
官方认证美国密歇根州立大学毕业证学位证书原版一模一样
官方认证美国密歇根州立大学毕业证学位证书原版一模一样官方认证美国密歇根州立大学毕业证学位证书原版一模一样
官方认证美国密歇根州立大学毕业证学位证书原版一模一样
 
john krisinger-the science and history of the alcoholic beverage.pptx
john krisinger-the science and history of the alcoholic beverage.pptxjohn krisinger-the science and history of the alcoholic beverage.pptx
john krisinger-the science and history of the alcoholic beverage.pptx
 
The Python for beginners. This is an advance computer language.
The Python for beginners. This is an advance computer language.The Python for beginners. This is an advance computer language.
The Python for beginners. This is an advance computer language.
 
Generative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of contentGenerative AI leverages algorithms to create various forms of content
Generative AI leverages algorithms to create various forms of content
 
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have oneISPM 15 Heat Treated Wood Stamps and why your shipping must have one
ISPM 15 Heat Treated Wood Stamps and why your shipping must have one
 
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
Redefining brain tumor segmentation: a cutting-edge convolutional neural netw...
 
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming PipelinesHarnessing WebAssembly for Real-time Stateless Streaming Pipelines
Harnessing WebAssembly for Real-time Stateless Streaming Pipelines
 
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdfBPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
BPV-GUI-01-Guide-for-ASME-Review-Teams-(General)-10-10-2023.pdf
 
Material for memory and display system h
Material for memory and display system hMaterial for memory and display system h
Material for memory and display system h
 

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