SW 그리고 아빠 엔지니어링 중...

아는 만큼 보이고, 경험해봐야 알 수 있고, 자꾸 써야 내 것이 된다.

concurrency 26

memory order 조정 이야기

프로그램 코드들은 기계어로 변환되어 메모리에 올라가고 fetch, decode, execute를 반복하며 수행이 된다. L fetch(명령어 가져오기) decode (명령어 해석하기) execute (명령어 실행기) 이때 메모리 순서라고 하는 것은 결국 CPU가 메모리에 있는 명령어를 읽는 순서를 말하는데 pc -> 0x0000 mov .... 0x0001 add .... 0x0002 mov .... *pc (프로그램 카운터) 이 순서가 컴파일 시 컴파일러에 의해 혹은 런타임 중에 CPU에 의해 조정될 수 있기에 이에 대해 알아보자. CPU에 의해 조정되는 메모리 순서아래 표에도 나와있지만 모든 CPU가 메모리 순서 조정을 지원하진 않는다. 전통적인 아키텍처인 X86과 AMD, 즉 당신의 PC는 메모리 ..

L C++/Concurrency 2024.01.30

[Concurrency] lock-free와 mutex사이 spin lock

2024.01.16 - [L C++] - [Concurrency] ❇ std::atomic ❇의 이해 이전 글에서는 lock-free 관점에서 쓰다 보니 spin lock은 쓰면 안 되는 것처럼 생각할 수 있는데 본 글에서 spin lock의 필요성에 대해 이야기하고자 한다. spin lock의 필요성 이해 context switching에 따른 오버헤드 발생 Context switching은 CPU가 현재 실행 중인 프로세스나 스레드를 중단하고 다른 프로세스나 스레드를 실행하는 작업을 말한다. 우선 아래 예제를 보자. 예제 1 두 개의 스레드가 공유 데이터를 호출하는데 공유 데이터 접근은 mutex로 처리한 프로그램 코드이다. #include #include #include #include std::m..

L C++/Concurrency 2024.01.23

[Concurrency] ❇ std::atomic ❇의 이해

발행 : 2014/01/16 수정 : 2014/01/20 - atomic에 대한 전체 내용에 대한 링크 추가 - 메모리 오더 옵션에 대한 정보 추가 - gcc에서 is_lock_free 가 에러 나는 이유 추가 본 글을 atomic 중 lock free에 대해 중점적으로 설명한 내용입니다. (상세 설명은 제일 밑 참고에 링크를 추가하였습니다.) atomic의 사전적 의미 원자성(原子性, atomicity)은 어떤 것이 더 이상 쪼개질 수 없는 성질을 말한다. 어떤 것이 원자성을 가지고 있다면 원자적(atomic)이라고 한다. 생각해 봅시다. C++ 코드에서 원자적인 것은 어떤 것이 있을까요? 한 줄짜리 코드인 x++ 는 원자적일까요? 정답은 아니다. 한 줄짜리 x++을 기계어로 변환하면 아래와 같이 3개..

L C++/Concurrency 2024.01.16

[Concurrency] C++20 스레드 조정 메커니즘 std::latch와 std::barrier

C++20부터 latch and barrier 가 필요한 이유? 2023.11.28 - [L C++] - [Concurrency] std::jthread - join 없이 사용하기📌 C++ 20부터 join을 알아서 해주는 jthread가 생겼다. 하지만 기존 thread를 대체하기에는 아직 문제가 있는데 어떤 문제가 있는지 아래 의사코드(pseudocode)에서 확인해 보자. main() { std::thread() together_working() std::join() after_working() } : thread와 동시에 together_working이 실행되고, 스레드 종료 이후에 after_working이 실행되었던 것을 main() { std::jthread() together_working..

L C++/Concurrency 2024.01.09

[Concurrency] mutex의 lock/unlock 관리 도구 소개 (2/2)

이전 글에서 2023.12.29 - [L C++] - [Concurrency] mutex의 lock/unlock 관리 도구 소개 (1/2) RAII 원칙을 지키는 mutex의 lock/unlock 관리도구를 2가지 소개했는데 나머지 2가지를 알아보자. std::lock_guard (C++11) std::scoped_lock (C++17) std::unique_lock (C++11) std::shared_lock (C++14) std::unique_lock Since C++11 unique_lock은 기능이 많다. (lock_guard를 포함한 확장 버전이라고 생각하면 좋을 것 같다.) 예제를 통해서 unique_lock의 특징을 확인해 보자. 예제 1-1 unique_lock의 특징을 테스트한 프로그램 ..

L C++/Concurrency 2024.01.02

[Concurrency] mutex의 lock/unlock 관리 도구 소개 (1/2)

이전 글에서 2023.12.19 - [L C++] - [Concurrency] 다양한 mutex 소개 deadlock 방지 사례와 성능 향상에 대한 mutex 소개가 있었는데 C++ Core guidelines에 보면 lock()/unlock()을 직접 사용하지 말라고 합니다. 😨 CP.20: Use RAII, never plain lock()/unlock() * RAII : Resource Acquisition Is Initialization. (자원의 획득은 초기화 과정이다. => 자원의 획득은 (자원관리 객체의) 초기화 과정이다. => 자원 관리는 항상 생성자/소멸자에 의존해라.) 왜? mutex 사용 시 RAII를 쓰라고 하는 이유에 대해 함께 알아봅시다. mutex 사용 시 RAII를 쓰라고 하..

L C++/Concurrency 2023.12.29

[Concurrency] 다양한 mutex 소개

C++ mutex는 몇 개 알고 계신가요? C++ mutex는 6개이다. 아래 글에서 mutex를 다뤘으니 볼드체로 된 3 가지만 알아볼 텐데, (나머지 2개는 조합이니 관심 있는 분은 개별로 알아보세요.) 이 mutex 들을 통해 아래 이슈에 대한 해결이 가능하게 된다. 1. lock 중에 lock을 호출하여 deadlock이 발생하는 문제 해결 방법은? 2. 공유데이터를 읽을 때 속도를 향상 시키는 방법은? 3. 한정된 시간에 lock에 예외를 발생시키는 방법은? mutex(C++11), recursive_mutex(C++11), shared_mutex(C++17) timed_mutex(C++11), recursive_timed_mutex(C++11), shared_timed_mutex(C++14) ..

L C++/Concurrency 2023.12.19

[Concurrency] std::call_once - 중복 초기화 해소 기술

중복으로 초기화를 해야 하는 경우 보통 어떻게 하시나요? 저는 이럴 경우 flag를 둬서 두 번 호출하게 하지 않거나, 기존 함수를 한 번만 호출되는 함수와 두 번 호출되는 함수로 분리하는 방식으로 수정했었습니다. 여러분은 어떻게 하시나요? 생각해 봅시다. 예를 들어 아래 foo 함수 내에서 init 그리고 work 함수를 호출하는 foo를 멀티 스레드로 동작시키는 경우를 생각해 보자. foo -> init -> work 아래와 같이 실행이 될 텐데 Thread 1 : foo -> init -> work Thread 2 : foo -> init -> work 예제 1 foo를 다수의 스레드로 실행하여 스레드 수만큼 init이 실행되는 프로그램 코드이다. #include #include #include #..

L C++/Concurrency 2023.12.12

[Concurrency] thread_local - thread 전용 변수 ✔

생각해 봅시다. Process 끼리는 메모리 할당이 서로 접근할 수 없게 독립적으로 분리되어 있다. 이런 콘셉트로 스레드끼리도 메모리를 독립적으로 쓸 수 있는 방법은 없을까? 🙄 필요성을 좀 더 느끼기 위해 아래 예제를 봅시다. A, B 스레드 각각 독립적으로 1씩 증가하여 3을 만드는 프로그램을 짜는데 지역변수를 사용하면 원하는 결과가 안 나온다. n을 어떻게 선언하면 이 문제를 해결할 수 있을까? 지역 변수 n 예제 1 A, B 스레드 각각 독립적으로 1씩 증가를 지역변수 n을 이용한 프로그램 코드이다. #include #include #include //thread_local int n = 0; int increase() { int n = 0; // 지역변수, 스택 사용 //static int n ..

L C++/Concurrency 2023.12.05

[Concurrency] std::jthread - join 없이 사용하기📌

C++에서 join(혹은 detach) 없이 사용할 수 있는 thread는? 바로 jthread와 async가 떠오르지 않았다면 본 글에서 std::jthread를 알아보자. (async는 아래 글 참조) 2023.11.21 - [L C++] - [thread] std::async - 기존 함수 그대로 thread에 적용(2) std::jthread 란? C++ 20에 추가된 클래스로, 모듈에 포함되어 있고, 크게 두 가지 기능을 가지고 있는 스레드이다. joining thread : 클래스에 join이 포함되어 있어 따로 join을 하지 않아도 된다. cooperatively interruptible : 협력적으로 중단(취소)이 가능하다. Joining thread(스레드 결합) 주 스레드가 종료하면 ..

L C++/Concurrency 2023.11.28
320x100