*배운내용을 토대로 직접 취합하고 기술한 내용입니다.

개요

명령어 재배치(Instruction Reordering)나 메모리 배리어 같은 저수준 동기화, 메모리 모델 제어는 임베디드, 커널, 락프리 라이브러리, 하드웨어 제어 등 성능과 동기화가 극도로 중요한 분야에서 주로 고려된다.

게임서버의 컨텐츠 로직, 비즈니스 로직 등에서는 유지보수성, 코드명확성, 개발속도 등이 훨씬 더 중요하기 때문에 이와 관련된 내용을 신경쓸 필요가 거의 없다.

다만 한쪽에서는 Interlocked로 변수를 바꾸고, 다른쪽에서는 일반대입으로 진행하는 경우 명령어 재배치로 인해 코드가 의도된대로 동작하지 않는 문제를 경험했다. 이에 명령어 재배치가 무엇인지, 그리고 이를 방지할 수 있는 메모리 베리어에 대해서도 추가적으로 알아본다.

Out-Of-Order 종류

1. CPU

명령어를 프로그램에 작성된 순서와 다르게 실행하는 기술로, 파이프라인 효율 극대화로 성능향상을 노린다.

명령어 A,B,C가 있을 때, B보다 C가 먼저 실행될 수 있음. 최종결과는 프로그램 순서와 동일하게 보장한다.

2. 컴파일러

(2)와 같은 결로, 컴파일러가 명령어를 재배치(redordering)해서 out-of-order 실행을 유도할 수 있음

이 외에도 SDD/HDD I/O요청에 대한 명령어 재배치, DB에서 여러 쿼리나 트랜잭션이 최적화를 위해 순서를 바꾸는 행위 등 이 있다. 여기서는 명령어 재배치(Instruction Reordering)를 뜻하는 명령어 재배치를 알아본다.

CPU 명령어 재배치 (Instruction Reordering)

명령어 재배치는 컴파일러나 CPU가 프로그램의 명령어(연산) 순서를 바꾸는 것으로, 결과에는 영향을 미치지 않으나 성능향상을 노릴 수 있는 기법이다. (파이프라인 효율, 병렬성 증가, 메모리 접근 최적화 등)

CPU는 여러 명령어를 동시에 처리할 수 있지만, 여러가지 이유 때문에 대기하는 경우가 많다. 따라서 의존성 없는 명령어를 먼저 실행하면 CPU자원을 더 효율적으로 활용 가능하다.

(CPU가 대기하는 여러가지 이유로는 분기예측 실패, 구조적 해저드, 레지스터 충돌, 메모리 배리어나 락으로 인한 메모리 일관성 동기화, I/O대기, 파이프라인 플러시 등이 있다.)