티스토리 뷰

C\\C++

[C/C++] restrict 키워드

아몬드통 2023. 1. 24. 15:34

linux pthread 공부 중, 처음 보는 restrict 키워드가 나와서 간단 정리해보자.

  • int pthread_create(pthread_t* restrict thread, const pthread_attr_t* restrict attr, void* (start_routine)(void*), void* restrict arg);
  • pthread의 원형 코드다. 무작정 사용할때는 몰랐는데 자세히 보니까 처음보는 restrict라는 코드가 있었다.

 

무엇인가?

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=lighting12&logNo=221130109551 

 

[c언어] restrict 포인터

:: Alias rule :: 어떤 함수가 2개 이상의 포인터를 파라미터로 가지고 있을 때 생기는 컴파일링 규칙에 ...

blog.naver.com

  • 위 내용이 개념은 아주 정확하게 설명해주고 있는 것 같다.
  • 함수에 2개 이상의 포인터가 존재할때 포인터들이 서로 같은 메모리를 가르키는지(혹은 겹치는 주소가 있는지) 검사하는 것을 Alias rule 이라 한다.
  • Alias rule은 결국 하나의 추가 조건이 붙는 것이므로 성능 저하를 시킬 수 있는 부분이다.
  • 그래서 2개 이상의 포인터가 서로 같은 메모리를 가르키지 않는다는 것을 보장할 수 있을 때 Alias rule을 사용해서 검사하지 말라고 컴파일러에게 알려주는 키워드가 restrict이다.

 

이게 뭐지????

  • 처음 보고는 잘 이해가 안됐는데 계속 읽고, 그림과 같이 보니 조금 이해가 됐다.
void swap(int* a, int* b){
	int  temp = *a;
	*a = *b;
	*b = *temp;
}
  • 위에서 설명한대로 swap함수는 2개 이상의 포인터를 가지고 있다. 이때 컴파일러는 Alias rule 검사를 한다는 것이다.
  • a와 b가 서로 같은 주소를 가리키고 있고, 값은 1025 라고 가정해보자.(각 메모리는 2진수 값으로 표현)
  • 이때 *a = *b 연산을 메모리에서 복사한다고 하면 이런 그림일 것이다.

1번 그림

  • 사실 그림과 실제 연산결과를 테스트 해봐도 위 코드는 문제가 없다.
  • 같은 메모리 주소에 같은 값을 넣는 게 전부이기 때문이다.
  • 그럼 이번에는 메모리가 같은 주소는 아니지만 겹치는 것을 가정해보자.

2번 그림

  • 마찬가지로 작은 주소에서 큰주소로 올라가면서 복사가 된다고 가정해보자.
  • 여기서는 아주 큰 문제가 발생한다. 복사의 순서는 아래와 같다.
    • 0x08 = 0x06
    • 0x09 = 0x07
    • 0x0a = 0x08
    • 0x0b = 0x09
  • 이때 3번째 0x0a = 0x08에서 0x08의 값은 얼마인가?
  • 원래 0x08의 값은 1이었다. 하지만 첫번째 복사에서 0x06의 값을 0x08로 복사한다.
  • 그러므로 0x08의 값은 3이 되고 3번째 복사를 실행하면 0x0a는 1이 아닌 3이 복사되게 된다.
  • 그래서 결과는 3,7,3,7 이 되어버린다.
  • 이 문제를 막기 위해서는 복사의 순서를 반대로 하면 된다. 0x0b = 0x09 부터 위로 복사를 하게 되면 3,7,1,4 가 잘 복사 된다.
  • 그리고 이렇게 위에서부터 복사할 것인지 아래서부터 복사할것인지를 판단하기 위해서 컴파일러는 함수의 인자로 포인터가 2개 이상일때 따로 검사를 하는 것이다.
  • 이것 말고도 따져야 할 조건이 많지만 restrict에 필요한 설명만 했다.

 

restrict의 기능

2번 그림

void swap(int* restrict a, int* restrict b){
	int  temp = *a;
	*a = *b;
	*b = *temp;
}
  • 2번 그림과 restrict가 적용된 swap코드이다.
  • 만약 restrict키워드를 주지 않았다면 컴파일러는 주소의 대소 비교를 하여 주소값이 높은 부분부터 복사할것인지 낮은 부분부터 복사할 것인지 검사를 할것이다.
  • 하지만 이렇게 restrict 키워드를 주게 되면 컴파일러는 주소 검사를 하지않고 기본적인 순서로(컴파일러마다 상이함)복사를 할것이고, 문제가 발생할 수도 있다.
  • 그래서 restrict 키워드를 사용하는 함수를 사용하거나, 만들때는 포인터가 가리키는 주소값이 겹치지 않는 다는 것을 보장 해주어야 문제가 발생하지 않는다!

 

더 자세한 사항은 아래 참조 글들을 읽어보자!

 

참조

https://bigpel66.oopy.io/library/c/etc/1

 

C99 restrict 키워드와 memcpy & memmove 함수

1. restrict 키워드

bigpel66.oopy.io

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=chhh92&logNo=220516562592 

 

[C] restrict 키워드

man posix_spawn(3) 을 보면 아래와 같이 prototype이 정의되어있다.   12345678int posix_spawn...

blog.naver.com

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=lighting12&logNo=221130109551 

 

[c언어] restrict 포인터

:: Alias rule :: 어떤 함수가 2개 이상의 포인터를 파라미터로 가지고 있을 때 생기는 컴파일링 규칙에 ...

blog.naver.com

 

 

 
댓글