만족

[Linux Kernel] RCU (Read-Copy Update) 본문

[Linux Kernel] RCU (Read-Copy Update)

기타 CS 이론/Kernel Satisfaction 2021. 6. 15. 05:04

요즘 대부분의 컴퓨터가 멀티코어 환경인 만큼 

프로그램 개발 시 발생하는 동기화 문제에 대해

얼마나 성능 감소를 완화시킬 수 있을지가 매우 중요하다.

 

실제로 우리가 동일한 성능을 가진 코어가 있을 때,

1코어 CPU와 2코어 CPU를 비교하면 2코어 CPU의 성능이 2배 빠를 것으로 기대하지만,

실제로 차이는 그보다 훨씬 적다.

 

코어 갯수가 늘어날 수록 동기화 문제가 점점 복잡해지고 그에 따라 Overhead가 커지기 때문인데,

오늘은 이런 동기화 성능 감소치를 비약적으로 낮춘 RCU에 대해 알아볼 것이다.

 

문제

어떤 문자열 포인터가 있다고 해 보자.

 

이 문자열 포인터에 N개의 스레드가 접근해 Read하려고 하고

M개의 스레드가 접근해 Write하려고 하는 상황이다.

 

N개의 스레드가 Read하는 도중 1개의 스레드가 Write 해버리면

일부 Reader들은 Writer와 싱크가 맞지 않아 Null(writer에 의해 새로운 데이터가 쓰여지고, 기존 문자열 포인터는 free됨)값을 읽어버릴 수도 있다.

 

따라서 N+M개의 스레드가 하나의 key에 대해 await해야만 한다.

 

그런데 사실 위의 문제는 읽기+쓰기가 동시다발적으로 일어날 때의 일인데,

만약 읽기만 N개 요청한다면 어떻게 될까?

 

여전히 하나의 key에 대해 await해야 하기 때문에

모든 Reader들이 직렬화되어 실행된다.

 

Writer가 작동중이 아닐 때는 이런 동기화 작업이 필요가 없게 되어

아무런 역할도 하지 못하고 오히려 성능만 저하시키는 것이다.

 

RCU (Read-Copy Update)

RCU에서는 N개의 Reader와 M개의 Writer가 동시에 발생했을 때,

M개의 Writer를 실제 메모리에 반영시키기 전에 변경 전 값을 따로 복사해 보관하고, 데이터를 변경한다.

 

N개의 Reader는 Writer가 데이터를 변경하기 전 복사된 값을 읽게 된다.

 

이렇게 되면 Reader들은 일관된 값을 가질 수 있으며,

병렬적으로 동작할 수 있게 되어 엄청난 성능 향상이 있다.

 

또한 Writer 역시 Reader가 실제 그 데이터를 읽는 것이 아니라, 복사된 값을 읽는 것이기 때문에

Reader와 어느 정도 병렬적으로 실행될 수 있다.

 

실제로 rwlock(reader에 대해 병렬성을 지원하는 기능)과

rcu(reader/writer에 대해 병렬성을 지원하는 기능)를 비교해 보면

Core 갯수에 따른 성능 저하 폭 역시 굉장히 완만해진 모습을 볼 수 있다.

 

(rwlock은 위에서 설명한 문제에서 reader의 병렬성을 해결한 기능이다.

rcu와 rwlock이 이정도 차이를 보이는데...

rcu와 고전적인 sync 방법을 비교하면 더욱 더 큰 차이가 발생한다)

 

RCU의 사용

char* data= NULL;

...
char* read(void){
  char temp;
  char* result= kmalloc(sizeof(char), GFP_KERNEL);
  rcu_read_lock();
  
  //직접 접근하지 않고 복사된 값을 참조해야 하기 때문에
  //rcu_dereference를 통해 접근한다
  temp= rcu_dereference(data);
  *result= temp;
  
  rcu_read_unlock();
  return result;
}

void write(char* new_data){
  rcu_assign_pointer(data, new_data);
}

...

rcu_read_lock()~rcu_read_unlock()이 의미하는 것이 

spin_lock()~spin_unlock()처럼 다른 컨텍스트의 진입을 막는 것이 아니라

일종의 reader가 얼마나 있는지를 판단하기 위한 reader counter라고 보면 된다.

 

'기타 CS 이론 > Kernel' 카테고리의 다른 글

[Linux Kernel] Real-Time CPU Scheduling  (0) 2021.06.15
[Linux Kernel] Deferrable Functions  (0) 2021.06.15
[Linux Kernel] Interrupt  (0) 2021.06.15
[Linux Kernel] Kernel Linked List  (0) 2021.03.28


Comments