gcc가 C에서 일부 명령문을 최적화하는 것을 방지하는 방법은 무엇입니까?


107

페이지를 더티하게 만들기 위해 (페이지 테이블 항목에서 더티 비트로 전환) 다음과 같이 페이지의 첫 번째 바이트를 터치합니다.

pageptr[0] = pageptr[0];

그러나 실제로 gcc는 데드 스토어 제거에 의한 명령문을 무시합니다. gcc 최적화를 방지하기 위해 다음과 같이 문을 다시 작성합니다.

volatile int tmp;
tmp = pageptr[0];
pageptr[0] = tmp;

트릭이 작동하는 것처럼 보이지만 다소 추합니다. 동일한 효과를 갖는 지시문이나 구문이 있는지 알고 싶습니다. 그리고 나는 -O0플래그 를 사용하고 싶지 않습니다 . 왜냐하면 그것은 또한 큰 성능 저하를 가져올 것이기 때문입니다.


8
@Mark -O0은 최적화를 중지하지만 프로그램 성능을 저하시킵니다. 이 코드 스 니펫의 최적화를 막고 싶습니다. P
ZelluX 2010

-O0예를 들어 GCC가 일부 코드가 효과가 없음을 감지하면 단순히 제거하는 것과 같이, 예를 들어 GCC를 사용하더라도 죽은 코드 "최적화"를 방지 할 수 없었습니다. AFAIK 이것은 전에도 무대입니다 -O0... 그러나 그것은 단지 나의 경험입니다
smoothware

답변:


91

최적화를 해제하면 문제가 해결되지만 불필요합니다. 더 안전한 대안은 컴파일러가 volatile형식 한정자 를 사용하여 저장소를 최적화하는 것을 불법으로 만드는 것 입니다.

// Assuming pageptr is unsigned char * already...
unsigned char *pageptr = ...;
((unsigned char volatile *)pageptr)[0] = pageptr[0];

volatile컴파일러에 지시 타입 한정자는 메모리 저장 및로드에 대한 엄격합니다. 의 한 가지 목적은 volatile메모리 액세스에 부작용이 있으므로 유지되어야 함을 컴파일러에 알리는 것입니다 . 이 경우 저장소는 페이지 오류를 유발하는 부작용이 있으며 컴파일러가 페이지 오류를 보존하기를 원합니다.

이렇게하면 주변 코드를 계속 최적화 할 수 있으며 코드를 GCC #pragma또는 __attribute__구문을 이해하지 못하는 다른 컴파일러로 이식 할 수 있습니다.


2
나는 이것이 최적화를 끄는 것보다 낫다고 말하고 싶습니다. 이 방법을 사용하여 다른 최적화의 이점을 계속 누릴 수 있습니다.
Ben S

3
Dietrich Epp의 솔루션은 ARM4.1 컴파일러에서 작동하지 않습니다 . ZelluX의 솔루션조차 작동하지 않습니다. ARM4.1에서이 작업을 수행하는 다른 방법은 ZelluX의 솔루션 인 ' temp '를 전역 휘발성 변수로 만드는 것 입니다.
Oculus Dexter 2011

1
그것은 컴파일러에게 꽤 나쁩니다.
Alexey Frunze 2011

1
@Shocker : GCC는 실제 메모리 액세스를 최적화하지 않고도 변수를 최적화 할 수 있습니다. 그것들은 다른 문제입니다.
Dietrich Epp

2
@jww :이 사용법은 해당 블로그 게시물에 설명 된 내용과 일치합니다. volatile메모리 액세스가 기록 된대로 발생해야 함을 의미합니다. 즉, 우리는 그것에 대해 신중하게 생각했고 그것이 의미한다고 생각하는 것을 의미합니다.
Dietrich Epp

184

당신이 사용할 수있는

#pragma GCC push_options
#pragma GCC optimize ("O0")

your code

#pragma GCC pop_options

GCC 4.4 이후 최적화를 비활성화합니다.

자세한 내용은 GCC 문서를 참조하십시오.


3
그러나 이것은 특정 설명이 아닌 전체 함수에서만 작동한다는 점에 주목할 가치가 있습니다. gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/… "이 시점 이후에 정의 된 각 함수는 마치 attribute (( 해당 함수에 대해 optimize ( "STRING")))가 지정되었습니다. ".
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

134

새 pragma를 사용하는 대신 __attribute__((optimize("O0")))필요에 따라 사용할 수도 있습니다 . 이는 동일한 파일에 정의 된 모든 기능이 아닌 단일 기능에만 적용하는 이점이 있습니다.

사용 예 :

void __attribute__((optimize("O0"))) foo(unsigned char data) {
    // unmodifiable compiler code
}

3
-Olevel옵션을 사용하지 않지만 개별적으로 켜진 개별 옵션을 사용한 경우 어떻게됩니까? (제 경우에는 코드를 깨뜨리는 개별 최적화 옵션을 결정할 수 없습니다) .
user2284570 apr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.