파이프라인: 데이터 처리 단계의 출력이 다음 단계의 입력으로 이어지는 형태로 연결된 구조를 가리킨다.
이렇게 연결된 데이터 처리 단계는 한 여러 단계가 서로 동시에, 또는 병렬적으로 수행될 수 있어 효율성의 향상을 꾀할 수 있다.
명령어 파이프라인: 같은 CPU 회로 안에서 여러 명령어들이 단계적으로 수행되는 것을 가리킨다.
각 명령어는 다시 페치, 디코딩, 연산 등의 세부 주기로 나뉘어 각 파이프라인 단계에 의해 수행된다.
Fetch -> Decode -> Execute
모든 CPU의 명령주기가 동일하지는 않지만, 위와 같이 기본 3가지 사이클에 맞춰 동작한다.
해당 과정에서 CPU는 결과값이 바뀌지 않는 상태에서 좀 더 효율적인 순서로 동작한다.
https://ko.wikipedia.org/wiki/%EB%AA%85%EB%A0%B9_%EC%A3%BC%EA%B8%B0
명령 주기 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 명령 실행 주기 도표 명령 주기(命令週期, 영어: instruction cycle, machine cycle)는 마이크로프로세서(CPU)가 메모리로부터 프로그램 된 한개의 기계어 명령어를 가져
ko.wikipedia.org
우리가 작성한 코드는 컴파일러를 통해 기계어로 번역된다.
컴파일러는 모든 코드를 단일스레드 형태로 분석하고 결과가 바뀌지 않는 형태에서 최적화를 진행한다.
int x = 0;
int y = 0;
int r = 0;
void func1(){
y = 1; // save
r = x; // load
}
위와 같이 데이터를 저장 후 로드하는 함수를 만들었을 경우 컴파일러는 CPU 명령어 파이프라인과 비슷하게 함수의 결과값을 바꾸지 않는 형태에서 아래와 같은 최적화를 진행할 수 있다.
void func1(){
r = x; // load
y = 1; // save
}
싱글스레드 환경에서는 이런 변형이 문제가 발생하지 않는다.
멀티스레드 환경에서 문제점
다음과 같은 코드에서는 문제가 발생한다.
1. 코드의 가시성
2. 코드 재배치
#include "pch.h"
#include "CorePch.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <future>
#include <windows.h>
int32 x = 0;
int32 y = 0;
int32 r1 = 0;
int32 r2 = 0;
volatile bool ready;
void Thread_1() {
while (!ready)
;
y = 1;
r1 = x;
}
void Thread_2() {
while (!ready)
;
x = 1;
r2 = y;
}
int main()
{
int32 count = 0;
while (true) {
ready = false;
count++;
x = y = r1 = r2 = 0;
thread t1(Thread_1);
thread t2(Thread_2);
ready = true;
t1.join();
t2.join();
if (r1 == 0 && r2 == 0) {
break;
}
}
cout << count << endl;
}
메인함수에서 t1과 t2스레드는 메인스레드와 같이 멀티스레드 환경에서 동작된다.
r1과 r2는 함수에서 변수를 불러오므로 반복문을 탈출하지 못하여야 하지만, 멀티스레드 환경때문에 순차적으로 로직이 진행되지 않아 count가 출력된다.
이를 해결하기 위한 방법으로 원자적 연산을 활용할 수 있다.
https://juzdalua.tistory.com/215
메모리 모델과 원자적(atomic) 연산
여러 스레드가 동일한 메모리에 동시에 접근하는 경우가 있다.read 연산에서는 문제가 발생하지 않지만, write 연산에서는 문제가 발생한다.Race Contidion(경합조건) 이라고도 한다.이런 현상을 Undefin
juzdalua.tistory.com
'Server > C++' 카테고리의 다른 글
TLS(Thread Local Storage) (0) | 2024.07.31 |
---|---|
메모리 모델과 원자적(atomic) 연산 (0) | 2024.07.31 |
캐시(Cache)와 CPU (1) | 2024.07.30 |
Future와 Asynchronous (0) | 2024.07.30 |
조건변수 (Condition Variable) (0) | 2024.07.30 |