문제

나는 K & R을 읽고 레지스터 변수에 대한 작은 섹션에 왔으며, 여기 사람들 이이 일에 대한 좋은 예를 가지고 있는지 궁금해하고있었습니다.

K & R의 4.7 절에서 :

레지스터 선언은 모양입니다
int x 등록;
char c 등록;

분명히, 나는 멋진 코드 샘플을보고 싶어합니다. 나는 (내가) 주제를 이해한다고 확신하므로, 당신이 원하지 않는 한 장구적인 설명을 입력 할 필요가 없다고 생각하지 마십시오.

도움이 되었습니까?

해결책

최신 컴파일러를 사용할 때 (읽기 : 지난 15 년 이상) 레지스터 사용의 좋은 예는 없습니다. 레지스터를 사용할 때는 컴파일러에 "내 코드보다 내 코드를 더 잘 최적화하는 방법을 알고 있습니다"라고 말합니다. 레지스터를 사용할 때 세 가지 중 하나가 발생할 수 있습니다.

  • 컴파일러는 그것을 무시합니다. 이것은 아마도 가능성이 높습니다. 이 경우 유일한 피해는 코드에서 변수의 주소를 취할 수 없다는 것입니다.
  • 컴파일러는 귀하의 요청을 존중하고 결과적으로 코드가 느리게 실행됩니다.
  • 컴파일러는 귀하의 요청을 존중하고 코드가 더 빨리 실행되므로 이는 가장 적은 시나리오입니다.

하나의 컴파일러가 레지스터를 사용할 때 더 나은 코드를 생성하더라도 다른 컴파일러가 동일하게 할 것이라고 믿을 이유가 없습니다. 컴파일러가 충분히 최적화하지 않는 중요한 코드가 있다면 가장 좋은 방법은 어쨌든 해당 부분에 어셈블러를 사용하는 것이지만 물론 생성 된 코드를 먼저 확인하기 위해 적절한 프로파일 링을 수행합니다.

다른 팁

일반적으로 나는 동의합니다 로버트, 그러나, 좋은 지적으로 이것은 예외도 있습니다.
깊게 포함 된 시스템을 작업하는 경우 컴파일러보다 코드를 최적화하는 방법보다 더 잘 알 수 있습니다. 특정 하드웨어 아키텍처에 대한 특정 응용 프로그램.

그러나 99%의 경우 Roberts 설명은 내장 된 단어에도 좋습니다.

나는 이것이 꽤 오랫동안 왔다는 것을 알고 있지만 여기에 레지스터 변수를 사용하면 최소한 GCC 4.5.2를 사용하여 코드를 컴파일하는 것입니다.

inline  void max_heapify(int *H, int i){
    char OK = FALSE;
    register int l, r, max, hI;
    while(!OK){
        OK = TRUE;
        l = left(i);
        r = right(i);
        max = i;
        if(l <= H[SIZE] && H[l] > H[i]){
            max = l;
        }
        if(r <= H[SIZE] && H[r] > H[max]){
            max = r;
        }
        if(max != i){
            OK = FALSE;
            hI = H[i];
            H[i] = H[max];
            H[max] = hI;
            i = max;
        }
    }
}

속성 전에 레지스터 키워드 유무에 관계없이 Algortihm을 테스트하고 각 버전에 대해 몇 번 몇 번 노트북에 50,000,000 요소의 임의 배열을 정렬하기 위해 실행했습니다.

레지스터의 사용은 HeapSort 시간을 ~ 135S에서 ~ 125로 떨어 뜨 렸습니다.

또한 5,000,000 개의 요소 만 테스트했지만 더 많은 시간을 실행했습니다.

레지스터가없는 버전은 11 초에 시작되었지만 각 실행은 9,65 초에 도달 할 때까지 시간을 낮추고 그에 중점을 두었습니다.

레지스터가있는 버전은 10 초에 시작하여 8,80 년대까지 시간을 낮췄습니다.

캐시 메모리와 관련이 있다고 생각합니다. 그럼에도 불구하고 레지스터는 Constanct Factor에 의해 알고리즘을 더 빨리 만드는 것 같습니다.

이러한 변수는 알고리즘을 따라 매우 많이 사용 되므로이 작업을 컴파일러에 맡기지 않고 레지스터에 있는지 확인 하여이 경우 더 나은 결과를 얻었습니다. 그러나 시간이 많이 향상되지 않았습니다.

바라건대 Thill은 누군가에게 도움이 될 것입니다.

또 다른 일반적인 사례는 저수준 통역사를 구현할 때입니다. 일부 상태를 레지스터에 유지합니다. 가상 머신 스택 포인터는 메모리 액세스를 크게 줄이고 코드 속도를 높일 수 있습니다.

보다 VMGEN - 효율적인 가상 기계 통역사의 생성기 최적화의 예 (스택 캐싱의 5.2 상단).

첫째, 액세스 시간을 최소화하여 성능을 향상시키기 위해 루프 제어 변수와 같은 중고 변수에 레지스터 변수를 사용해야합니다. 보조 당신은이 상황에서만 사용할 수 있으며, 재미 (Auto Int A, Auto Int B) : Error Fun (int a, int b)과 같은이 상황에서만 레지스터 스토리지 지정자 만 사용할 수 있습니다. 정적 int b) : 오류 재미 (Extern Int A, Extern Int B) : 오류

글쎄, 이것은 여러 개의 코딩 컨텍스트가 있기 때문에 여러 답변이 필요한 질문입니다. 높은 수준의 언어 관점에서 C 언어가 어셈블리 루틴을 호출 할 수 있기 때문에 중간 레벨 및 낮은 레벨 (조립까지).

C 대신 어셈블리를 사용하는 이유는 개발 중에 발생하는 성능 문제로 인해 절실 적입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top