C의 제한 키워드

Abdul Mateen 2023년10월12일
  1. C의 컴파일러 최적화
  2. C에서 restrict 키워드
  3. C++의 restrict 키워드
  4. 결론
C의 제한 키워드

이 튜토리얼에서는 C의 restrict 키워드와 컴파일러 최적화를 위한 용도에 대해 설명합니다. 따라서 먼저 컴파일러 최적화에 대해 논의할 것입니다.

다음으로 코드 예제와 함께 C의 restrict 키워드에 대해 설명합니다. 마지막으로 C 언어의 restrict 키워드에 대해 간략하게 살펴보고 마치겠습니다.

C의 컴파일러 최적화

컴파일러의 중요한 기능은 최적화 도구입니다. 일반적으로 컴파일러는 고급 언어 프로그램을 기계 수준 프로그램으로 변환하는 것으로 간주되고 교육됩니다.

그러나 최신 컴파일러는 코드 최적화도 수행합니다.

코드 최적화는 실행 시간, 메모리 사용량 및 전력 소비를 최소화합니다. 이 작업은 문장을 번역할 뿐만 아니라 문장을 수정하여 더 좋게 만드는 똑똑한 번역가와 유사합니다.

컴파일러 최적화는 동일한 출력을 생성하지만 최소한의 리소스(주로 시간과 스토리지)를 소비하는 동등한 코드를 생성하기 위한 최적화 변환으로 구성된 매우 정교한 프로세스입니다.

여기에서 컴파일러 최적화와 그 유용성을 이해하는 한 가지 예를 볼 수 있습니다. 매우 간단한 프로그램을 고려하십시오.

#include <stdio.h>
int main() {
  int i;
  for (i = 1; i <= 10; i++) printf("%d ", i);
  return 0;
}

출력:

1 2 3 4 5 6 7 8 9 10

이것은 매우 간단한 프로그램입니다. 그러나 프로그램은 1에서 10까지 세는 것을 인쇄하는 것 외에 몇 가지 추가 단계를 수행합니다. 비교 및 증분 단계는 최소 10회 수행됩니다. 오히려 비교는 11번 수행됩니다(즉, 11번째 반복에 대해 truefalse를 10번).

총 32개의 문을 사용하여 이 개수를 인쇄합니다. 첫 번째 문은 초기화입니다.

11개의 비교문. 10개의 증가 문과 10개의 인쇄 문.

컴파일러는 위의 코드에 포함된 상수를 쉽게 판단하고 아래 코드와 같은 동등한 코드를 생성할 수 있습니다.

#include <stdio.h>

int main() {
  printf("%d ", 1);
  printf("%d ", 2);
  printf("%d ", 3);
  printf("%d ", 4);
  printf("%d ", 5);
  printf("%d ", 6);
  printf("%d ", 7);
  printf("%d ", 8);
  printf("%d ", 9);
  printf("%d ", 10);
  return 0;
}

위의 코드는 이전 코드와 동일한 출력을 갖습니다. 단일 print 문도 동일한 출력을 생성할 수 있습니다.

이것은 단순한 예일 뿐입니다. 그러나 최신 컴파일러는 가능한 한 많은 리소스를 최소화하기 위해 많은 정교한 최적화를 수행합니다.

C에서 restrict 키워드

C99 표준은 restrict 키워드를 도입합니다. 이 키워드는 포인터를 형식 한정자로 선언할 때 사용됩니다.

새로운 기능을 추가하지 않습니다. 그러나 특정 최적화를 수행하도록 컴파일러에 알리는 데만 사용됩니다.

이 키워드는 포인터와 함께 사용되어 이것이 변수/메모리를 사용하는 유일한 포인터이고 동일한 메모리에 액세스하는 다른 포인터가 없음을 컴파일러에 알립니다.

이것은 쓸모없는 정보인 것 같습니다. 그러나 이 컴파일러는 다른 포인터가 동일한 메모리에 액세스하지 않는다는 정보를 받습니다. 따라서 메모리 로딩/언로딩에 대한 추가 검사를 적용할 필요가 없습니다.

restrict 키워드 구문

restrict 키워드는 * 뒤와 변수 이름 앞에 포인터 선언과 함께 추가됩니다.

int* restrict x;

분명히 이 키워드는 코드의 기능에 영향을 미치지 않습니다. 따라서 코드에서 restrict 키워드를 사용할 수 있는 방법을 설명하는 한 가지 예를 제공합니다.

#include <stdio.h>

void f1(int *a, int *restrict b) { printf("%d %d\n", *a, *b); }
int main() {
  int x = 100, y = 200;
  f1(&x, &y);
  return 0;
}

이 코드에서 restrict 키워드는 f1 함수의 두 번째 매개 변수와 함께 한정자로 추가됩니다.

이 키워드는 이 포인터가 액세스하는 메모리가 배타적이며 다른 포인터가 동일한 메모리에 액세스하지 않음을 컴파일러에 알립니다. 따라서 컴파일러는 어셈블리 코드를 단순하게 유지함으로써 최적화를 수행할 수 있습니다.

출력:

100 200

다시 말하지만 restrict 키워드를 제거하더라도 출력은 동일하게 유지됩니다.

C++의 restrict 키워드

놀랍게도 C++에서는 restrict 키워드 사용을 허용하지 않는다는 점에 유의하는 것도 중요합니다.

당신은 그것을 구글 수 있습니다; 그러나 이것이 C++에서 이 기능을 지원하지 않는다는 의미는 아닙니다. C++에는 이 기능이 암시적으로 있으며 컴파일러에는 이러한 유형의 제한을 식별하는 자동 방법이 있으며 그에 따라 최적화가 수행됩니다.

결론

컴파일러는 리소스 최적화를 위해 몇 가지 코드 최적화를 추가합니다. restrict는 컴파일러가 더 나은 최적화 결정을 내리는 데 도움이 되는 플래그입니다.

restrict 키워드는 C99 이전의 C 언어에서 지원되지 않았습니다. 이 키워드는 어떤 기능도 추가하지 않습니다. 오히려 컴파일러에게 이 메모리 액세스가 배타적이고 제한적임을 알립니다. 따라서 컴파일러는 변환된 대상 어셈블리 코드에서 필요한 최적화를 수행합니다.

restrict 키워드가 있거나 없는 코드 기능에는 차이가 없습니다. 마지막으로 C++는 이 키워드를 명시적으로 지원하지 않습니다.