SlideShare a Scribd company logo
1 of 59
Download to read offline
NHN NEXT 1기
이진우 (jwlee@nhnnext.org)
C++ 메모리 모델과,
Atomic type 연산
Chapter 5
문제는 메모리
왜 메모리가 문제인가?
변수는 메모리에 저장됩니다
직접 메모리를 읽고 쓴다고 생각하시겠지만…
CPU
요즘 CPU에는,
L1, L2, L3 캐쉬까지 있습니다
(사진 속 L1, L2는 코어 안에…)
메모리는 멀고 느립니다
버스 타고 다녀야 해요
그래서 매번 메모리를 직접 읽고 쓰지는 않습니다
이 챕터에서 해결 할 문제들
멀티 쓰레딩은 쉽지 않습니다
동시에 접근하면
무슨 일이?
(Data race)
전부 Lock을 쓰면
느려지지 않을까?
(Lock-free)
쓰레드 사이의
자료구조는?
(동기화 문제)
메모리 모델
• C++11 표준의 중요한 변화
– 멀티 쓰레딩 고려 (이전엔 고려하지 않음)
• 대부분의 프로그래머는 인식하지 못함
– 그냥 mutex나 condition variable 사용
– 저게 “왜” 동작하는지는 중요하지 않음
• 그런데 왜 알아야 하나?
– 고성능을 위해서 : Low-level 접근 필요
C++ 표준 위원회의 생각
성능을 위해 low level 언어를 사용 할 필요가 없도록 하자.
Low-level 동기화 기능 지원 - CPU 명령을 절약할 수 있음
Object & Memory location
• Object : C++에서 데이터의 구성 단위
– 객체지향에서의 “object”와는 다른 용어
– 변수도 object, 구조체도 object
– 구조체 안의 멤버도 각각 하나의 object
• 모든 Object는 Memory location을 가짐
– 심지어 0바이트 크기를 가진 object 조차도…
• 기본 데이터 형 (int, char)
– 정확히 하나의 memory location (크기 무관)
Undefined
behavior
Data race
하나라도 Atomic이 아닌 연산이 있고,
하나라도 쓰기 연산이 있다면,
 Undefined behavior ( 동작이 정의되어 있지 않음 )
Thread 1
Thread 2 (같은 위치)
Thread 3
동시 접근
Undefined behavior
전체 프로그램이 그 무엇도 예측할 수 없는 상태가 된다
컴파일러나 운영체제의 책임 한계를 벗어난 영역
수정 순서 (Modification order)
실행 할 때 마다 바뀔 수 있지만, (non-deterministic)
Atomic도 아니고 프로그래머가 순서를 맞춰주지 않으면,
data race 발생으로 undefined behavior
Thread 1 write
Thread 3 write
Thread 1 write
Thread 2 write
Thread 4 write
Thread 1 write
Thread 3 write
Thread 3 write
Thread 2 write
“Object A”(시간)
Thread 1
Thread 4
Thread 2
Thread 3
수정 순서 (Modification order)
(2)에서 읽은 값이 (1)에서 쓰여진 값이라면,
(3)의 쓰기 작업은 (1)보다 나중이다. (쓰레드 1에서만 보장)
Atomic 타입이거나 단일 쓰레드에서는,
이런 것들이 추가적인 장치 없이 항상 보장 되지만,
멀티 쓰레드에서는 동기화를 신경 써야 한다.
Object A 읽기(2)
Object A 쓰기(3)
쓰레드 1(시간)
Object가 Atomic type이 아닐 때,
프로그래머가 동기화의 책임이 있음
Object가 Atomic type일 때,
컴파일러가 필요한 작업을 해 줌
Object A 쓰기(1)
다른 쓰레드
Atomic Operation (원자적 연산)
• Atomic(원자적)이란?
– 더 이상 쪼개질 수 없고 독립적으로 실행
– 부분적으로 실행된 상태는 존재하지 않음
– Data race를 방지
• C++ 에서는…
– Atomic type 변수를 선언하여 사용
Atomic 없이 사용하면?
Non-atomic 쓰기
쓰는 도중에
다른 쓰레드에서
엉뚱한 값을 읽음
Non-atomic 읽기
일부분을 읽은 후
다른 쓰레드에서 수정
이후 나머지 부분을 읽음
이런 문제가 생길 수도 있음
(캐시 라인에 걸쳤거나 캐시 라인보다 큰 object)
※ data race 문제와는 별개 (이 쪽이 진짜 문제)
표준 Atomic type
std::atomic<bool> atomic_bool std::atomic<long> atomic_long
std::atomic<char> atomic_char std::atomic<signed char> atomic_schar
std::atomic<int> atomic_int std::atomic<unsigned char> atomic_uchar
다른 이름들…
이 외에도 다 있지만 그냥 std::atomic<> 쓰세요…
• 실행 중에 확인 할 수 있음
– true : atomic instruction 사용
– false : 에뮬레이션 (내부적으로 lock 사용)
lock-free 체크
std::atomic_flag
• 단순한 사용법
• lock-free 보장
– 따라서 lock-free 체크 메소드가 아예 없음
이것은 Spinlock이 아닙니다
일반 변수를 이용하여 Spinlock 구현하려고 한 예
정상적으로 동작하지 않음
이것은 Spinlock이 아닙니다
두 쓰레드가 동시에 변경 가능
Spinlock
std::atomic_flag 를 이용한 spinlock 구현
( while문을 빠져 나오는 쓰레드는 한번에 하나만 가능 )
std::atomic<bool>
• 가장 기본적인 타입
– 기본적인 모든 기능들 존재
– load(), store(), exchange(),
compare_exchange_weak(),
compare_exchange_strong()
Compare-and-swap (CAS)
• 조건부 swap
– 변수의 값과 주어진 값을 비교 후 교환
– 원래 값이 주어진 값일 때만 교환 되는 것이 보장됨
• compare_exchange_weak()
– 변수의 값이 다르면 : 실패
– 변수의 값이 같으면 : swap, (그런데 실패 할 수도 있음)
• compare_exchange_strong()
– 변수의 값이 다르면 : 실패
– 변수의 값이 같으면 : swap
Compare-and-swap 활용
while문을 이용하여 성공할 때까지 반복
누군가가 중간에서 값을 바꾸면, 실패하기 때문에 반복
Weak? Strong?
Weak : num이 x와 같아도 실패 할 수 있다
Strong : num이 x와 다른 경우에만 실패한다
x86 계열 CPU : 둘 다 strong 으로 동작한다
Weak ordered machine : strong은 loop로 구현되어 있다
std::atomic<T*>
• 기본적인 사용법은 동일
– load(), store(), exchange(),
compare_exchange_weak(),
compare_exchange_strong() 등등…
• 증감 연산 가능
std::atomic<(정수형)>
• 기본적인 사용법은 동일
– load(), store(), exchange(),
compare_exchange_weak(),
compare_exchange_strong() 등등…
• 거의 모든 연산 사용 가능
– fetch_add(), fetch_sub(), fetch_and(),
fetch_or(), fetch_xor(),
– +=, -=, &=, |=, ^=, ++x, x++, --x, x--
– 없는 것들은 compare_exchange_weak() 쓰면 됨
std::atomic<(기타)>
• User Defined Type (사용자정의타입)
– 가상 함수나 가상 클래스 사용 불가
– 기본 복사 생성자만 사용
– 비교 연산은 memcmp()와 같아야 한다.
• float, double
– 값이 같아도 compare_exchange가 실패할 수 있다.
• 워드 크기의 (32비트 머신은 32비트) UDT
– lock-free일 수 있다
– 워드의 두 배 크기까지 되는 머신이 가끔 있음
연산자들
atomic_
flag
atomic
<bool>
atomic
<T*>
atomic
<정수형>
atomic
<기타>
test_and_set() v
clear() v
is_lock_free() v v v v
load() v v v v
store() v v v v
exchange() v v v v
compare_exchange_weak(),
compare_exchange_strong()
v v v v
fetch_add, += v v
fetch_sub, -= v v
fetch_or, |= v
fetch_and, &= v
fetch_xor, ^= v
++, -- v v
동기화 & 강제 순서 지정
①번과 ④번에서 같은 데이터에 대한 non-atomic 접근이,
②, ③번의 Atomic 변수 “ready”에 대한 연산으로 의해
강제로 순서가 지정된다.
③
④
①
②
Happens-before 관계
① happens-before ②
③ happens-before ④
③
④
①
②
Synchronizes-with 관계
③에서 읽은 ready가 true가 되면,
write(②) synchronizes-with read(③)가 되면서,
happens-before 관계를 만들게 됨.
③
④
①
②
Happens-before는 이행 관계(transitive)
① happens-before ②, ③ happens-before ④,
그런데 ready가 true이면 ② happens-before ③,
따라서 ① happens-before ④.
③
④
①
②
Synchronizes-with 관계
Atomic 타입 연산으로만 얻어짐
“적절한 태그”  memory ordering (뒤에 나옴)
(적절히 태그된)
Write on X
(적절히 태그된)
Read X
Read-modify-
write on X
쓰레드 2 쓰레드 3
Write on X
or
or
메모리 순서 정렬 태그
• 크게 세가지로 구분
– sequentially consistent (순차 일관성)
– acquire-release
– relaxed
• 각각 비용이 다를 수 있음
– 이 부분은 CPU 아키텍처에 따라 달라짐
– relaxed  acq_rel 혹은 acq_rel  seq_cst
: 동기화 명령이 추가되는 경우도 있다
– CPU가 많아지면 실행 오버헤드가 커질 수 있다
– 반면 x86 등은 오버헤드가 상대적으로 적다
Strict consistent
• 책에 없는 옵션 (C++에는 존재하지 않음)
– 어떠한 상황에서도 모든 쓰레드가 가장 최근의
write를 읽을 수 있어야 함
Sequentially consistent
• 순차 일관성
– 가장 직관적이며 이해하기 쉬움
– 모든 atomic 연산의 기본값
• 전역적으로 일관된 수정 순서가 지켜짐
– 어떤 쓰레드에서 보여지는 수정 순서에 대해,
– 다른 쓰레드에서도 그 순서로 보여짐
• 비용 문제
– weakly order machine(alpha 등)에서 고비용
– x86에서는 낮은 편 (store만 약간의 overhead)
memory_order_seq_cst
Sequentially consistent
동시에 저장된다면,
(true, true), (true, false),
(false, true), (false, false) 모두 나올 수 있다.
x.store(true) y.store(true)
x.load()
y.load()
쓰레드 1 쓰레드 2 쓰레드 3
Sequentially consistent
(true, false)가 두 쓰레드에서 동시에 나올 수 있을까?
x.store(true) y.store(true)
x.load()
y.load()
y.load()
x.load()
쓰레드 1 쓰레드 2 쓰레드 3 쓰레드 4
Sequentially consistent
만약 쓰레드 3에서 (true, false)라고 나온다면,
x에 대한 수정이 y에 대한 수정보다 먼저이기 때문에,
쓰레스 4에서는 (true, false)가 나올 수 없음.
x.store(true) y.store(true)
x.load()
true
y.load()
false
y.load()
x.load()
쓰레드 1 쓰레드 2 쓰레드 3 쓰레드 4
Relaxed
• Synchronizes-with 관계를 만들지 않음
– Atomic함을 보장하는 최소한의 태그
• 연산들의 수정 순서가 바뀔 수 있음
– 변수의 수정 사항이 지연되어 전파
memory_order_relaxed
Relaxed
(true, false)가 나올 수 있다.
 나중에 수정된 y의 값이 보였음에도,
먼저 수정된 x의 값은 아직 적용되지 않았을 수 있다.
x.store(true)
y.store(true)
y.load()
x.load()
쓰레드 1 쓰레드 2
No
Sync-with
Relaxed
(true, false)가 나올 수 없다.
 Happens-before 관계는 유지
x.store(true)
y.store(true)
y.load()
x.load()
쓰레드 1 쓰레드 2
Any
Sync-with
Relaxed
(2, 1)은 나올 수 없다.
 동일 쓰레드, 동일 변수 - 수정 순서 역전은 있을 수 없다.
x.store(1)
x.store(2)
x.load()
x.load()
쓰레드 1 쓰레드 2
Acquire-release
• 부분적 일관성
– Acquire 태그 load, Release 태그 write 사이의
– Synchronized-with 관계만 보장
• 전역적 일관성은 보장하지 않음
– 다른 쓰레드에서는 다른 순서로 보여질 수 있음
• x86 프로세서에서는
– Relaxed 대비 동기화 명령이 추가되지 않음
(Reordering만 방지되는 정도)
memory_order_acquire
memory_order_release
Acquire-release
동시에 (true, false)가 나올 수 있다.
Sequentially consistent와 달리,
쓰레드 3과 쓰레드 4가 다른 순서를 볼 수 있다.
x.store(true) y.store(true)
x.load()
true
y.load()
false
y.load()
true
x.load()
false
쓰레드 1 쓰레드 2 쓰레드 3 쓰레드 4
Acquire-release
(false, true)는 나올 수 없다.
Relaxed와 달리, Synchronized-with 관계.
x.store(true)
y.store(true)
쓰레드 1 쓰레드 2
y.load()
x.load()
Acquire-release
Read(Acquire) 배리어 이후의 연산들과
Write(Release) 배리어 이전의 연산들에 대해
서로 순서가 바뀌지 않도록 보장한다.
Write
<Release>
쓰레드 1 쓰레드 2
Read
<Acquire>
Consume-release
• 더 제한적인 부분적 일관성
– Acquire-release와 같으나,
– 데이터 의존성이 있는 변수들만 보장.
• 데이터 의존성?
– (write) 변수에 값을 쓰기 위해 사용된 변수
– (read) 변수에 쓰여진 값을 사용한 변수
memory_order_consume
memory_order_release
Consume-release
변수 a, b 에 대해서만 happens-before 관계가 성립
※ std::kill_dependency(p) : 의존성 없이 값 사용
Write p
<Release>
쓰레드 1 쓰레드 2
Read p
<Consume>
b = *p
p = &a
Consume-release
Memory ordering
적용 범위
memory_order_relaxed -
memory_order_consume 읽기
memory_order_acquire 읽기
memory_order_release 쓰기
memory_order_acq_rel 읽기 + 쓰기
memory_order_seq_cst -
Memory ordering
Store
Operation
Load
Operation
Read-modify-write
Operation
memory_order_relaxed v v v
memory_order_consume x v v
memory_order_acquire x v v
memory_order_release v x v
memory_order_acq_rel x x v
memory_order_seq_cst v v v
사용 가능 여부
Fence
• 메모리 장벽 (Memory barrier)
– Atomic 변수를 수정하지 않고 메모리 순서 보장
– Relaxed 및 non-atomic 변수들을 이용 가능
간단 요약
지금까지 배운 내용
Undefined Behavior
어떤 값이 나올지, 무슨 일이 일어날지 보장 할 수 없음
Behavior defined (atomic, ordering)
항상 같은 결과가 나오는 것은 아니지만,
(0,0), (0,17), (37,17) 의 결과 중 하나
Atomic, not ordering
순서를 보장해 주지 않음. (대신 빠름)
(0,0), (0,17), (30,0), (37,17) 의 결과 중 하나
Ordered loads & stores
최소한의 오버헤드
(0,0), (0,17), (37,17) 의 결과 중 하나

More Related Content

What's hot

(2013 DEVIEW) 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
(2013 DEVIEW) 멀티쓰레드 프로그래밍이  왜이리 힘드나요? (2013 DEVIEW) 멀티쓰레드 프로그래밍이  왜이리 힘드나요?
(2013 DEVIEW) 멀티쓰레드 프로그래밍이 왜이리 힘드나요? 내훈 정
 
Multithread & shared_ptr
Multithread & shared_ptrMultithread & shared_ptr
Multithread & shared_ptr내훈 정
 
Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용흥배 최
 
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요NAVER D2
 
비동기 파일 로딩
비동기 파일 로딩비동기 파일 로딩
비동기 파일 로딩Bongseok Cho
 
Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumerChang Yoon Oh
 
242 naver-2
242 naver-2242 naver-2
242 naver-2NAVER D2
 
[2D7]레기온즈로 살펴보는 확장 가능한 게임서버의 구현
[2D7]레기온즈로 살펴보는 확장 가능한 게임서버의 구현[2D7]레기온즈로 살펴보는 확장 가능한 게임서버의 구현
[2D7]레기온즈로 살펴보는 확장 가능한 게임서버의 구현NAVER D2
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화sung ki choi
 
헤테로지니어스 컴퓨팅 : CPU 에서 GPU 로 옮겨가기
헤테로지니어스 컴퓨팅 :  CPU 에서 GPU 로 옮겨가기헤테로지니어스 컴퓨팅 :  CPU 에서 GPU 로 옮겨가기
헤테로지니어스 컴퓨팅 : CPU 에서 GPU 로 옮겨가기zupet
 
Memory & object pooling
Memory & object poolingMemory & object pooling
Memory & object poolingNam Hyeonuk
 
11_웹서비스활용
11_웹서비스활용11_웹서비스활용
11_웹서비스활용noerror
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현noerror
 
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기Daehee Kim
 
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장SukYun Yoon
 
[160402_데브루키_박민근] UniRx 소개
[160402_데브루키_박민근] UniRx 소개[160402_데브루키_박민근] UniRx 소개
[160402_데브루키_박민근] UniRx 소개MinGeun Park
 
병렬 프로그래밍
병렬 프로그래밍병렬 프로그래밍
병렬 프로그래밍준혁 이
 

What's hot (20)

(2013 DEVIEW) 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
(2013 DEVIEW) 멀티쓰레드 프로그래밍이  왜이리 힘드나요? (2013 DEVIEW) 멀티쓰레드 프로그래밍이  왜이리 힘드나요?
(2013 DEVIEW) 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
 
Multithread & shared_ptr
Multithread & shared_ptrMultithread & shared_ptr
Multithread & shared_ptr
 
Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용
 
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
 
비동기 파일 로딩
비동기 파일 로딩비동기 파일 로딩
비동기 파일 로딩
 
Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumer
 
242 naver-2
242 naver-2242 naver-2
242 naver-2
 
[2D7]레기온즈로 살펴보는 확장 가능한 게임서버의 구현
[2D7]레기온즈로 살펴보는 확장 가능한 게임서버의 구현[2D7]레기온즈로 살펴보는 확장 가능한 게임서버의 구현
[2D7]레기온즈로 살펴보는 확장 가능한 게임서버의 구현
 
Thread programming
Thread programmingThread programming
Thread programming
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
 
헤테로지니어스 컴퓨팅 : CPU 에서 GPU 로 옮겨가기
헤테로지니어스 컴퓨팅 :  CPU 에서 GPU 로 옮겨가기헤테로지니어스 컴퓨팅 :  CPU 에서 GPU 로 옮겨가기
헤테로지니어스 컴퓨팅 : CPU 에서 GPU 로 옮겨가기
 
Memory & object pooling
Memory & object poolingMemory & object pooling
Memory & object pooling
 
11_웹서비스활용
11_웹서비스활용11_웹서비스활용
11_웹서비스활용
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
 
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
 
pyOpenCL 입문
pyOpenCL 입문pyOpenCL 입문
pyOpenCL 입문
 
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
 
[160402_데브루키_박민근] UniRx 소개
[160402_데브루키_박민근] UniRx 소개[160402_데브루키_박민근] UniRx 소개
[160402_데브루키_박민근] UniRx 소개
 
Multi thread
Multi threadMulti thread
Multi thread
 
병렬 프로그래밍
병렬 프로그래밍병렬 프로그래밍
병렬 프로그래밍
 

Viewers also liked

[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11흥배 최
 
Telegram protocol
Telegram protocolTelegram protocol
Telegram protocolJinWoo Lee
 
Pro typescript.ch07.Exception, Memory, Performance
Pro typescript.ch07.Exception, Memory, PerformancePro typescript.ch07.Exception, Memory, Performance
Pro typescript.ch07.Exception, Memory, PerformanceSeok-joon Yun
 
C++ Concurrency in Action 9-2 Interrupting threads
C++ Concurrency in Action 9-2 Interrupting threadsC++ Concurrency in Action 9-2 Interrupting threads
C++ Concurrency in Action 9-2 Interrupting threadsSeok-joon Yun
 
[1116 박민근] c++11에 추가된 새로운 기능들
[1116 박민근] c++11에 추가된 새로운 기능들[1116 박민근] c++11에 추가된 새로운 기능들
[1116 박민근] c++11에 추가된 새로운 기능들MinGeun Park
 
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍Seungmo Koo
 

Viewers also liked (6)

[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11
 
Telegram protocol
Telegram protocolTelegram protocol
Telegram protocol
 
Pro typescript.ch07.Exception, Memory, Performance
Pro typescript.ch07.Exception, Memory, PerformancePro typescript.ch07.Exception, Memory, Performance
Pro typescript.ch07.Exception, Memory, Performance
 
C++ Concurrency in Action 9-2 Interrupting threads
C++ Concurrency in Action 9-2 Interrupting threadsC++ Concurrency in Action 9-2 Interrupting threads
C++ Concurrency in Action 9-2 Interrupting threads
 
[1116 박민근] c++11에 추가된 새로운 기능들
[1116 박민근] c++11에 추가된 새로운 기능들[1116 박민근] c++11에 추가된 새로운 기능들
[1116 박민근] c++11에 추가된 새로운 기능들
 
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
 

Similar to Concurrency in action - chapter 5

Concurrent programming
Concurrent programmingConcurrent programming
Concurrent programmingByeongsu Kang
 
자바 병렬 프로그래밍 1&2
자바 병렬 프로그래밍 1&2자바 병렬 프로그래밍 1&2
자바 병렬 프로그래밍 1&2HyeonSeok Choi
 
05_동기화_개요
05_동기화_개요05_동기화_개요
05_동기화_개요noerror
 
면접 대비 벡터, CS 개념과 사례
면접 대비 벡터, CS 개념과 사례면접 대비 벡터, CS 개념과 사례
면접 대비 벡터, CS 개념과 사례Soochan Park
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍Hyunsoo Jung
 
Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍흥배 최
 
Cassandra 멘붕기 | Devon 2012
Cassandra 멘붕기 | Devon 2012Cassandra 멘붕기 | Devon 2012
Cassandra 멘붕기 | Devon 2012Daum DNA
 
R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱jungjinwouk
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)익성 조
 
동시성 프로그래밍 하기 좋은 Clojure
동시성 프로그래밍 하기 좋은 Clojure동시성 프로그래밍 하기 좋은 Clojure
동시성 프로그래밍 하기 좋은 ClojureEunmin Kim
 
2017 tensor flow dev summit
2017 tensor flow dev summit2017 tensor flow dev summit
2017 tensor flow dev summitTae Young Lee
 
장재화, Replay system, NDC2011
장재화, Replay system, NDC2011장재화, Replay system, NDC2011
장재화, Replay system, NDC2011재화 장
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2Jinkyoung Kim
 
Redis trouble shooting
Redis trouble shootingRedis trouble shooting
Redis trouble shootingDaeMyung Kang
 
Assembly 스터디 1
Assembly 스터디 1Assembly 스터디 1
Assembly 스터디 1Jinkyoung Kim
 
if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04Klaytn
 
[OpenTRS-001] Hotel California
[OpenTRS-001] Hotel California[OpenTRS-001] Hotel California
[OpenTRS-001] Hotel CaliforniaTheori
 

Similar to Concurrency in action - chapter 5 (20)

Concurrent programming
Concurrent programmingConcurrent programming
Concurrent programming
 
자바 병렬 프로그래밍 1&2
자바 병렬 프로그래밍 1&2자바 병렬 프로그래밍 1&2
자바 병렬 프로그래밍 1&2
 
05_동기화_개요
05_동기화_개요05_동기화_개요
05_동기화_개요
 
면접 대비 벡터, CS 개념과 사례
면접 대비 벡터, CS 개념과 사례면접 대비 벡터, CS 개념과 사례
면접 대비 벡터, CS 개념과 사례
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍
 
Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍
 
Cassandra 멘붕기 | Devon 2012
Cassandra 멘붕기 | Devon 2012Cassandra 멘붕기 | Devon 2012
Cassandra 멘붕기 | Devon 2012
 
R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱
 
ES6 for Node.js Study 2주차
ES6 for Node.js Study 2주차ES6 for Node.js Study 2주차
ES6 for Node.js Study 2주차
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)
 
동시성 프로그래밍 하기 좋은 Clojure
동시성 프로그래밍 하기 좋은 Clojure동시성 프로그래밍 하기 좋은 Clojure
동시성 프로그래밍 하기 좋은 Clojure
 
2017 tensor flow dev summit
2017 tensor flow dev summit2017 tensor flow dev summit
2017 tensor flow dev summit
 
장재화, Replay system, NDC2011
장재화, Replay system, NDC2011장재화, Replay system, NDC2011
장재화, Replay system, NDC2011
 
Windows reversing study_basic_2
Windows reversing study_basic_2Windows reversing study_basic_2
Windows reversing study_basic_2
 
Redis trouble shooting
Redis trouble shootingRedis trouble shooting
Redis trouble shooting
 
Assembly 스터디 1
Assembly 스터디 1Assembly 스터디 1
Assembly 스터디 1
 
if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04
 
Java memory
Java memoryJava memory
Java memory
 
[OpenTRS-001] Hotel California
[OpenTRS-001] Hotel California[OpenTRS-001] Hotel California
[OpenTRS-001] Hotel California
 
Kubernetes
Kubernetes Kubernetes
Kubernetes
 

Recently uploaded

Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...Kim Daeun
 
A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)Tae Young Lee
 
Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)Wonjun Hwang
 
MOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution DetectionMOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution DetectionKim Daeun
 
캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차캐드앤그래픽스
 
Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)Wonjun Hwang
 

Recently uploaded (6)

Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
 
A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)
 
Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)
 
MOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution DetectionMOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution Detection
 
캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차
 
Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)
 

Concurrency in action - chapter 5

  • 1. NHN NEXT 1기 이진우 (jwlee@nhnnext.org) C++ 메모리 모델과, Atomic type 연산 Chapter 5
  • 3. 변수는 메모리에 저장됩니다 직접 메모리를 읽고 쓴다고 생각하시겠지만…
  • 4. CPU 요즘 CPU에는, L1, L2, L3 캐쉬까지 있습니다 (사진 속 L1, L2는 코어 안에…)
  • 5. 메모리는 멀고 느립니다 버스 타고 다녀야 해요 그래서 매번 메모리를 직접 읽고 쓰지는 않습니다
  • 6. 이 챕터에서 해결 할 문제들 멀티 쓰레딩은 쉽지 않습니다 동시에 접근하면 무슨 일이? (Data race) 전부 Lock을 쓰면 느려지지 않을까? (Lock-free) 쓰레드 사이의 자료구조는? (동기화 문제)
  • 7. 메모리 모델 • C++11 표준의 중요한 변화 – 멀티 쓰레딩 고려 (이전엔 고려하지 않음) • 대부분의 프로그래머는 인식하지 못함 – 그냥 mutex나 condition variable 사용 – 저게 “왜” 동작하는지는 중요하지 않음 • 그런데 왜 알아야 하나? – 고성능을 위해서 : Low-level 접근 필요
  • 8. C++ 표준 위원회의 생각 성능을 위해 low level 언어를 사용 할 필요가 없도록 하자. Low-level 동기화 기능 지원 - CPU 명령을 절약할 수 있음
  • 9. Object & Memory location • Object : C++에서 데이터의 구성 단위 – 객체지향에서의 “object”와는 다른 용어 – 변수도 object, 구조체도 object – 구조체 안의 멤버도 각각 하나의 object • 모든 Object는 Memory location을 가짐 – 심지어 0바이트 크기를 가진 object 조차도… • 기본 데이터 형 (int, char) – 정확히 하나의 memory location (크기 무관)
  • 10. Undefined behavior Data race 하나라도 Atomic이 아닌 연산이 있고, 하나라도 쓰기 연산이 있다면,  Undefined behavior ( 동작이 정의되어 있지 않음 ) Thread 1 Thread 2 (같은 위치) Thread 3 동시 접근
  • 11. Undefined behavior 전체 프로그램이 그 무엇도 예측할 수 없는 상태가 된다 컴파일러나 운영체제의 책임 한계를 벗어난 영역
  • 12. 수정 순서 (Modification order) 실행 할 때 마다 바뀔 수 있지만, (non-deterministic) Atomic도 아니고 프로그래머가 순서를 맞춰주지 않으면, data race 발생으로 undefined behavior Thread 1 write Thread 3 write Thread 1 write Thread 2 write Thread 4 write Thread 1 write Thread 3 write Thread 3 write Thread 2 write “Object A”(시간) Thread 1 Thread 4 Thread 2 Thread 3
  • 13. 수정 순서 (Modification order) (2)에서 읽은 값이 (1)에서 쓰여진 값이라면, (3)의 쓰기 작업은 (1)보다 나중이다. (쓰레드 1에서만 보장) Atomic 타입이거나 단일 쓰레드에서는, 이런 것들이 추가적인 장치 없이 항상 보장 되지만, 멀티 쓰레드에서는 동기화를 신경 써야 한다. Object A 읽기(2) Object A 쓰기(3) 쓰레드 1(시간) Object가 Atomic type이 아닐 때, 프로그래머가 동기화의 책임이 있음 Object가 Atomic type일 때, 컴파일러가 필요한 작업을 해 줌 Object A 쓰기(1) 다른 쓰레드
  • 14. Atomic Operation (원자적 연산) • Atomic(원자적)이란? – 더 이상 쪼개질 수 없고 독립적으로 실행 – 부분적으로 실행된 상태는 존재하지 않음 – Data race를 방지 • C++ 에서는… – Atomic type 변수를 선언하여 사용
  • 15. Atomic 없이 사용하면? Non-atomic 쓰기 쓰는 도중에 다른 쓰레드에서 엉뚱한 값을 읽음 Non-atomic 읽기 일부분을 읽은 후 다른 쓰레드에서 수정 이후 나머지 부분을 읽음 이런 문제가 생길 수도 있음 (캐시 라인에 걸쳤거나 캐시 라인보다 큰 object) ※ data race 문제와는 별개 (이 쪽이 진짜 문제)
  • 16. 표준 Atomic type std::atomic<bool> atomic_bool std::atomic<long> atomic_long std::atomic<char> atomic_char std::atomic<signed char> atomic_schar std::atomic<int> atomic_int std::atomic<unsigned char> atomic_uchar 다른 이름들… 이 외에도 다 있지만 그냥 std::atomic<> 쓰세요…
  • 17. • 실행 중에 확인 할 수 있음 – true : atomic instruction 사용 – false : 에뮬레이션 (내부적으로 lock 사용) lock-free 체크
  • 18. std::atomic_flag • 단순한 사용법 • lock-free 보장 – 따라서 lock-free 체크 메소드가 아예 없음
  • 19. 이것은 Spinlock이 아닙니다 일반 변수를 이용하여 Spinlock 구현하려고 한 예 정상적으로 동작하지 않음
  • 20. 이것은 Spinlock이 아닙니다 두 쓰레드가 동시에 변경 가능
  • 21. Spinlock std::atomic_flag 를 이용한 spinlock 구현 ( while문을 빠져 나오는 쓰레드는 한번에 하나만 가능 )
  • 22. std::atomic<bool> • 가장 기본적인 타입 – 기본적인 모든 기능들 존재 – load(), store(), exchange(), compare_exchange_weak(), compare_exchange_strong()
  • 23. Compare-and-swap (CAS) • 조건부 swap – 변수의 값과 주어진 값을 비교 후 교환 – 원래 값이 주어진 값일 때만 교환 되는 것이 보장됨 • compare_exchange_weak() – 변수의 값이 다르면 : 실패 – 변수의 값이 같으면 : swap, (그런데 실패 할 수도 있음) • compare_exchange_strong() – 변수의 값이 다르면 : 실패 – 변수의 값이 같으면 : swap
  • 24. Compare-and-swap 활용 while문을 이용하여 성공할 때까지 반복 누군가가 중간에서 값을 바꾸면, 실패하기 때문에 반복
  • 25. Weak? Strong? Weak : num이 x와 같아도 실패 할 수 있다 Strong : num이 x와 다른 경우에만 실패한다 x86 계열 CPU : 둘 다 strong 으로 동작한다 Weak ordered machine : strong은 loop로 구현되어 있다
  • 26. std::atomic<T*> • 기본적인 사용법은 동일 – load(), store(), exchange(), compare_exchange_weak(), compare_exchange_strong() 등등… • 증감 연산 가능
  • 27. std::atomic<(정수형)> • 기본적인 사용법은 동일 – load(), store(), exchange(), compare_exchange_weak(), compare_exchange_strong() 등등… • 거의 모든 연산 사용 가능 – fetch_add(), fetch_sub(), fetch_and(), fetch_or(), fetch_xor(), – +=, -=, &=, |=, ^=, ++x, x++, --x, x-- – 없는 것들은 compare_exchange_weak() 쓰면 됨
  • 28. std::atomic<(기타)> • User Defined Type (사용자정의타입) – 가상 함수나 가상 클래스 사용 불가 – 기본 복사 생성자만 사용 – 비교 연산은 memcmp()와 같아야 한다. • float, double – 값이 같아도 compare_exchange가 실패할 수 있다. • 워드 크기의 (32비트 머신은 32비트) UDT – lock-free일 수 있다 – 워드의 두 배 크기까지 되는 머신이 가끔 있음
  • 29. 연산자들 atomic_ flag atomic <bool> atomic <T*> atomic <정수형> atomic <기타> test_and_set() v clear() v is_lock_free() v v v v load() v v v v store() v v v v exchange() v v v v compare_exchange_weak(), compare_exchange_strong() v v v v fetch_add, += v v fetch_sub, -= v v fetch_or, |= v fetch_and, &= v fetch_xor, ^= v ++, -- v v
  • 30. 동기화 & 강제 순서 지정 ①번과 ④번에서 같은 데이터에 대한 non-atomic 접근이, ②, ③번의 Atomic 변수 “ready”에 대한 연산으로 의해 강제로 순서가 지정된다. ③ ④ ① ②
  • 31. Happens-before 관계 ① happens-before ② ③ happens-before ④ ③ ④ ① ②
  • 32. Synchronizes-with 관계 ③에서 읽은 ready가 true가 되면, write(②) synchronizes-with read(③)가 되면서, happens-before 관계를 만들게 됨. ③ ④ ① ②
  • 33. Happens-before는 이행 관계(transitive) ① happens-before ②, ③ happens-before ④, 그런데 ready가 true이면 ② happens-before ③, 따라서 ① happens-before ④. ③ ④ ① ②
  • 34. Synchronizes-with 관계 Atomic 타입 연산으로만 얻어짐 “적절한 태그”  memory ordering (뒤에 나옴) (적절히 태그된) Write on X (적절히 태그된) Read X Read-modify- write on X 쓰레드 2 쓰레드 3 Write on X or or
  • 35. 메모리 순서 정렬 태그 • 크게 세가지로 구분 – sequentially consistent (순차 일관성) – acquire-release – relaxed • 각각 비용이 다를 수 있음 – 이 부분은 CPU 아키텍처에 따라 달라짐 – relaxed  acq_rel 혹은 acq_rel  seq_cst : 동기화 명령이 추가되는 경우도 있다 – CPU가 많아지면 실행 오버헤드가 커질 수 있다 – 반면 x86 등은 오버헤드가 상대적으로 적다
  • 36. Strict consistent • 책에 없는 옵션 (C++에는 존재하지 않음) – 어떠한 상황에서도 모든 쓰레드가 가장 최근의 write를 읽을 수 있어야 함
  • 37. Sequentially consistent • 순차 일관성 – 가장 직관적이며 이해하기 쉬움 – 모든 atomic 연산의 기본값 • 전역적으로 일관된 수정 순서가 지켜짐 – 어떤 쓰레드에서 보여지는 수정 순서에 대해, – 다른 쓰레드에서도 그 순서로 보여짐 • 비용 문제 – weakly order machine(alpha 등)에서 고비용 – x86에서는 낮은 편 (store만 약간의 overhead) memory_order_seq_cst
  • 38. Sequentially consistent 동시에 저장된다면, (true, true), (true, false), (false, true), (false, false) 모두 나올 수 있다. x.store(true) y.store(true) x.load() y.load() 쓰레드 1 쓰레드 2 쓰레드 3
  • 39. Sequentially consistent (true, false)가 두 쓰레드에서 동시에 나올 수 있을까? x.store(true) y.store(true) x.load() y.load() y.load() x.load() 쓰레드 1 쓰레드 2 쓰레드 3 쓰레드 4
  • 40. Sequentially consistent 만약 쓰레드 3에서 (true, false)라고 나온다면, x에 대한 수정이 y에 대한 수정보다 먼저이기 때문에, 쓰레스 4에서는 (true, false)가 나올 수 없음. x.store(true) y.store(true) x.load() true y.load() false y.load() x.load() 쓰레드 1 쓰레드 2 쓰레드 3 쓰레드 4
  • 41. Relaxed • Synchronizes-with 관계를 만들지 않음 – Atomic함을 보장하는 최소한의 태그 • 연산들의 수정 순서가 바뀔 수 있음 – 변수의 수정 사항이 지연되어 전파 memory_order_relaxed
  • 42. Relaxed (true, false)가 나올 수 있다.  나중에 수정된 y의 값이 보였음에도, 먼저 수정된 x의 값은 아직 적용되지 않았을 수 있다. x.store(true) y.store(true) y.load() x.load() 쓰레드 1 쓰레드 2 No Sync-with
  • 43. Relaxed (true, false)가 나올 수 없다.  Happens-before 관계는 유지 x.store(true) y.store(true) y.load() x.load() 쓰레드 1 쓰레드 2 Any Sync-with
  • 44. Relaxed (2, 1)은 나올 수 없다.  동일 쓰레드, 동일 변수 - 수정 순서 역전은 있을 수 없다. x.store(1) x.store(2) x.load() x.load() 쓰레드 1 쓰레드 2
  • 45. Acquire-release • 부분적 일관성 – Acquire 태그 load, Release 태그 write 사이의 – Synchronized-with 관계만 보장 • 전역적 일관성은 보장하지 않음 – 다른 쓰레드에서는 다른 순서로 보여질 수 있음 • x86 프로세서에서는 – Relaxed 대비 동기화 명령이 추가되지 않음 (Reordering만 방지되는 정도) memory_order_acquire memory_order_release
  • 46. Acquire-release 동시에 (true, false)가 나올 수 있다. Sequentially consistent와 달리, 쓰레드 3과 쓰레드 4가 다른 순서를 볼 수 있다. x.store(true) y.store(true) x.load() true y.load() false y.load() true x.load() false 쓰레드 1 쓰레드 2 쓰레드 3 쓰레드 4
  • 47. Acquire-release (false, true)는 나올 수 없다. Relaxed와 달리, Synchronized-with 관계. x.store(true) y.store(true) 쓰레드 1 쓰레드 2 y.load() x.load()
  • 48. Acquire-release Read(Acquire) 배리어 이후의 연산들과 Write(Release) 배리어 이전의 연산들에 대해 서로 순서가 바뀌지 않도록 보장한다. Write <Release> 쓰레드 1 쓰레드 2 Read <Acquire>
  • 49. Consume-release • 더 제한적인 부분적 일관성 – Acquire-release와 같으나, – 데이터 의존성이 있는 변수들만 보장. • 데이터 의존성? – (write) 변수에 값을 쓰기 위해 사용된 변수 – (read) 변수에 쓰여진 값을 사용한 변수 memory_order_consume memory_order_release
  • 50. Consume-release 변수 a, b 에 대해서만 happens-before 관계가 성립 ※ std::kill_dependency(p) : 의존성 없이 값 사용 Write p <Release> 쓰레드 1 쓰레드 2 Read p <Consume> b = *p p = &a
  • 52. Memory ordering 적용 범위 memory_order_relaxed - memory_order_consume 읽기 memory_order_acquire 읽기 memory_order_release 쓰기 memory_order_acq_rel 읽기 + 쓰기 memory_order_seq_cst -
  • 53. Memory ordering Store Operation Load Operation Read-modify-write Operation memory_order_relaxed v v v memory_order_consume x v v memory_order_acquire x v v memory_order_release v x v memory_order_acq_rel x x v memory_order_seq_cst v v v 사용 가능 여부
  • 54. Fence • 메모리 장벽 (Memory barrier) – Atomic 변수를 수정하지 않고 메모리 순서 보장 – Relaxed 및 non-atomic 변수들을 이용 가능
  • 56. Undefined Behavior 어떤 값이 나올지, 무슨 일이 일어날지 보장 할 수 없음
  • 57. Behavior defined (atomic, ordering) 항상 같은 결과가 나오는 것은 아니지만, (0,0), (0,17), (37,17) 의 결과 중 하나
  • 58. Atomic, not ordering 순서를 보장해 주지 않음. (대신 빠름) (0,0), (0,17), (30,0), (37,17) 의 결과 중 하나
  • 59. Ordered loads & stores 최소한의 오버헤드 (0,0), (0,17), (37,17) 의 결과 중 하나