source

C 컴파일러는 연속된 할당을 휘발성 변수에 병합할 수 있습니까?

gigabyte 2022. 8. 29. 22:15
반응형

C 컴파일러는 연속된 할당을 휘발성 변수에 병합할 수 있습니까?

하드웨어 벤더에 의해 보고된 이론적인 하드웨어 문제(결정적이지 않고 테스트하기 어려우며 실제로 발생한 적이 없음)가 있습니다.이 문제로 인해 특정 메모리 범위에 대한 이중 워드 쓰기가 향후 버스 전송에 손상을 줄 수 있습니다.

C코드에 명시적으로 더블워드를 쓰는 것은 아니지만 컴파일러가 (현재 또는 미래의 구현에서) 인접한 여러 개의 워드 할당을 하나의 더블워드 할당으로 통합할 수 있을지 걱정입니다.

컴파일러는 휘발성 물질의 할당 순서를 변경할 수 없지만, 병합이 순서 변경으로 간주되는지는 불분명합니다.직감적으로 그렇긴 한데, 언어 변호사한테 교정 받은 적 있어!

예:

typedef struct
{
   volatile unsigned reg0;
   volatile unsigned reg1;
} Module;

volatile Module* module = (volatile Module*)0xFF000000u;

// two word stores, or one double-word store?
module->reg0 = 1;
module->reg1 = 2;

(컴파일러 벤더에 따로 문의해 보겠습니다만, 표준의 표준/커뮤니티 해석은 어떤 것입니까?)

아니요, 컴파일러는 이 두 개의 쓰기를 단일 이중 단어 쓰기로 최적화하는 것은 절대 허용되지 않습니다.최적화와 부작용에 대한 부분이 너무 흐릿하게 쓰여 있어서 기준을 인용하기가 좀 어렵습니다.관련 부품은 C17 5.1.2.3에 수록되어 있다.

이 국제 표준의 의미 설명은 최적화 문제가 무관한 추상 기계의 동작을 기술한다.

휘발성 개체에 액세스하거나 개체를 수정하거나 파일을 수정하거나 이러한 작업을 수행하는 함수를 호출하는 것은 모두 실행 환경 상태의 변경입니다.

추상기계에서 모든 표현은 의미론에 의해 지정된 대로 평가된다.실제 구현에서는 그 값이 사용되지 않고 필요한 부작용이 발생하지 않는다고 추론할 수 있는 경우(함수를 호출하거나 휘발성 객체에 액세스하여 발생하는 부작용 포함)에는 표현의 일부를 평가할 필요가 없습니다.

휘발성 객체에 대한 액세스는 추상 머신의 규칙에 따라 엄격하게 평가됩니다.

구조의 일부에 액세스 하면, 그 자체가 부작용이며, 컴파일러가 판단할 수 없는 결과를 초래할 수 있습니다.예를 들어 구조가 하드웨어 레지스터 맵이고 이러한 레지스터를 특정 순서로 작성해야 한다고 가정합니다.예를 들어 일부 마이크로컨트롤러 매뉴얼은 "reg0은 하드웨어 주변기기를 활성화하며 reg1에서 세부사항을 설정하기 전에 에 기입해야 합니다."와 같은 경우가 있습니다.

파 that the the the the the the the the the 를 병합하는 입니다.volatile오브젝트 기입이 1개로 흐트러지지 않고 완전히 파손됩니다.

컴파일러는 단일 메모리 쓰기에 이러한 두 개의 할당을 수행할 수 없습니다.코어에서 두 개의 독립된 쓰기가 있어야 합니다.@Lundin의 답변은 C 표준에 대한 관련 참조를 제공합니다.

그러나 캐시가 있는 경우 속일 수 있습니다. " " "volatile 의미하지 .해체된" 기억을 의미하는 것은 아닙니다. '아예'를 쓰는 것 volatile또한 주소 0xFF000000이 캐시되지 않은 것으로 매핑되어 있는지 확인해야 합니다.주소가 캐시된 것으로 매핑되어 있는 경우 캐시 HW에 의해2개의 할당이1개의 메모리 쓰기로 변환되는 경우가 있습니다.즉, 캐시된 메모리의 경우 2개의 코어 메모리 쓰기 조작이 시스템 메모리인터페이스의 1개의 쓰기 조작으로 끝날 가능성이 있습니다.

volatile님은 구현에 따라 달라지는 것 같습니다.부분적으로는 "휘발성 수식 유형을 가진 객체에 대한 액세스를 구성하는 것은 구현 정의입니다."라는 이상한 문장이 있기 때문입니다.

ISO C 99 섹션 5.1.2.3에는 다음과 같은 것도 있습니다.

3 추상기계에서 모든 표현은 의미론에 의해 지정된 대로 평가된다.실제 구현에서는 그 값이 사용되지 않고 필요한 부작용이 발생하지 않는다고 추론할 수 있는 경우(함수를 호출하거나 휘발성 객체에 액세스하여 발생하는 부작용 포함)에는 표현의 일부를 평가할 필요가 없습니다.

, '아주 좋다'는 것은volatile오브젝트는 추상적 의미론(즉 최적화되지 않음)에 따라 처리되어야 하며, 이상하게도 추상적 의미론 자체가 최적화의 예인 데드 코드와 데이터 흐름을 제거할 수 있습니다.

무슨 일이 일어났는지 알 수 있을까요?volatile의지와 의지는 컴파일러의 매뉴얼에 따라야 합니다.

C 표준은 휘발성 객체에 대한 작업과 실제 머신에 대한 작업 간의 어떠한 관계에도 의존하지 않습니다.에서는, 「이러다」와 같은 만,*(char volatile*)0x1234 = 0x56;는 값 0x1234에 하여 0x56을 0x1234로 지정합니다.실장에서는 여유시간에 8192바이트 배열 등의 공간을 할당하여 다음과 같이 지정할 수 있습니다.*(char volatile*)0x1234 = 0x56;는 하드웨어 주소 0x1234를 사용하지 않고 어레이의 요소 0x56을 즉시 저장합니다.또는 어레이의 0x1234에서 발생하는 모든 것을 하드웨어 주소 0x56에 정기적으로 저장하는 프로세스를 실장할 수도 있습니다.

적합성을 위해 필요한 것은 단일 스레드 내의 휘발성 객체에 대한 모든 작업이 Abstract 머신의 관점에서 완전히 시퀀싱된 것으로 간주된다는 것입니다.이 기준서의 관점에서, 구현은 그러한 접근을 적합하다고 판단되는 방식으로 실제 기계 운영으로 전환할 수 있다.

이를 변경하면 프로그램의 관찰 가능한 동작이 변경됩니다.따라서 컴파일러는 허용되지 않습니다.

언급URL : https://stackoverflow.com/questions/67616174/is-a-c-compiler-allowed-to-coalesce-sequential-assignments-to-volatile-variables

반응형