[C]restrict키워드
1️⃣ restrict 키워드란?
- 포인터 변수의 주소가 겹치지 않는다고 컴파일러에게 알려줘서
최적화 를 잘할 수 있게 해줍니다.
(1) restrict 간단한 예시
gcc -g -O3 -c C파일
로 오브젝트파일로 만든 뒤objdump -S C파일
을 이용하여 어셈블리어를 살펴봤습니다.-g
: 디버깅 정보를 삽입(g1,g2,g3 단계로 사용가능)-O3
: 인라인함수수준으로 최적화(O0,O1,O2등 단계가 있음)-c
: 오브젝트 파일로 생성objdump
: 간단히말하면 기계어를 어셈블리 코드로 변환-S
: 어셈블리소스 전체를 보여줌
- Mac M1의 Vscode환경에서 진행하였습니다. (어셈블리어는 운영체제나 컴파일러등등
환경 에 따라 다르게 작성됩니다)
<restrict사용X>
<restrict사용O>
- restrict키워드를 사용하지 않았을 때는
바꼈을지도 모르는 3번째 인자값을 다시 받아왔습니다. - restirct키워드를 사용했을 때는
처음에 받아온 것을(w8) 그대로 사용합니다. - 과연 주소를 겹치게 보낸다면 어떤 결과가 나올지 함수에 아래와같은 인자를 넣어 봤습니다.
add(&num1, &num2, &num1);
add_restrict(&num1, &num2, &num1);
- 위와같이
주소를 겹치게 함수를 사용하더라도 결과가 동일하게 나왔습니다. - 즉,
restrict키워드가 주소가 겹치는 것을 막아주지는 않습니다. - 개인적으로 결과값이 다르게 나오는 경우를 찾아보고 싶었지만 찾지는 못했습니다.. (restrict키워드를 쓰나 안쓰나, 주소값이 겹쳐도 결과 값이 같게 나온다면 굳이 최적화를 안해줄 필요가 있나라는 생각이 들었기 때문)
1️⃣ restrict키워드 특이케이스
(1) restrict키워드가 더 최적화를 못하는 경우
- 여러코드들을 실험해보는 중에 오히려 restrict키워드가 더 최적화를 못하는 경우가 보였습니다.
- Mac M1의 Vscode환경에서 진행하였고 다른 환경에서는 다른 결과가 나올 수 있습니다.
<예외케이스>
- 배열의 인덱스 역할을 하는
cnt
변수를재사용하여 while문에 사용 했을 경우 입니다.
void copy(char* dst1, char* dst2, const char* src)
{
int dst_size1, dst_size2;
int cnt;
cnt = 0;
/* dst1에 src를 복사하는 코드 생략(while문)*/
dst1[cnt] = '\0';
cnt = 0;
/* dst2에 src를 복사하는 코드 생략(while문)*/
dst2[cnt] = '\0';
}
<restrict사용X>
<restrict사용O>
- 위의 결과처럼 배열의 인덱스 역할을할
cnt
변수를함수 내부에서 재활용 했을 경우 restric키워드를 사용했을때 스텍을4바이트 를 더 차지했습니다. - 그래서
변수를 재사용 하는 것 대신에 cnt2`변수를 추가로 선언하여 사용해 봤습니다.
<restrict사용X>
<restrict사용O>
- 위의처럼
변수의 재사용 을 없애니 최적화가 훨씬 잘 됐습니다. - restrict키워드를 잘 사용하고 싶으면
함수내부에서 선언한 변수 의 사용도 신경써야할 것같습니다.
(2) **restrict키워드**를 굳이 사용하는 이유
- 위에서도 언급한 “
(restrict키워드를 쓰나 안쓰나, 주소값이 겹쳐도 결과 값이 같게 나온다면 굳이 최적화를 안해줄 필요가 있나라는 생각 “에 대한 제 나름대로의 정리입니다. (환경에 따라 다를 수 있고 개인적인 생각입니다)
- 주소가 겹치지 않는 변수를 사용할때만 최적화이득이 있기 때문 잘못사용하면 오히려 손해
함수 사용자 가 함수선언부에 표시된restrict키워드 를 보고 조심히 사용하도록 하는 목적