asm, asm 휘발성 및 방해 메모리의 차이점
잠금없는 데이터 구조 및 타이밍 코드를 구현할 때 종종 컴파일러의 최적화를 억제해야합니다. 일반적으로 사람들은 clobber 목록에서 asm volatile
with memory
를 사용하여이 작업을 수행 하지만 때로는 단순한 asm volatile
또는 단순한 asm
기억을 볼 수 있습니다.
이러한 서로 다른 명령문이 코드 생성에 어떤 영향을 미칩니 까 (특히 GCC에서 이식성이 떨어질 것 같지 않음)?
참고로 다음은 흥미로운 변형입니다.
asm (""); // presumably this has no effect on code generation
asm volatile ("");
asm ("" ::: "memory");
asm volatile ("" ::: "memory");
GCC 문서 의 "Extended Asm"페이지를 참조하십시오 .
뒤에
asm
키워드를 쓰면 명령어가 삭제되는 것을 방지 할 수 있습니다 . [...] 키워드는 명령어에 중요한 부작용이 있음을 나타냅니다. 도달 가능한 경우 GCC는 asm을 삭제하지 않습니다 .volatile
asm
volatile
volatile
과
asm
모든 출력없이 피연산자 명령은 휘발성 동일하게 처리 될asm
명령.
예제에 출력 피연산자가 지정되어 있지 않으므로 asm
및 asm volatile
양식은 동일하게 작동합니다. 코드에 도달 할 수없는 것으로 입증되지 않는 한 삭제할 수없는 지점을 생성합니다.
이것은 아무것도하지 않는 것과 완전히 다릅니다. 코드 생성을 변경 하는 더미의 예를 보려면 이 질문 을 참조하십시오. 이asm
예에서 루프를 1000 번 돌게하는 코드는 한 번에 16 번의 반복을 계산하는 코드로 벡터화됩니다. 그러나 asm
루프 내부 의 존재 는 최적화를 방해합니다 ( asm
1000 번에 도달해야 함).
"memory"
소지품은 GCC는 어떤 메모리를 임의로 읽거나 의해 기록 될 수 있다고 가정한다 asm
그래서 걸쳐로드 또는 저장을 재정렬에서 컴파일러를 방지 할 수 블록 :
이로 인해 GCC는 어셈블러 명령어에서 레지스터에 캐시 된 메모리 값을 유지하지 않고 해당 메모리에 대한 저장 또는로드를 최적화하지 않습니다.
(그래도 CPU가 다른 CPU와 관련하여로드 및 저장 순서를 재정렬하는 것을 막지는 못합니다.이를 위해서는 실제 메모리 배리어 명령이 필요합니다.)
asm ("")
아무 일도하지 않습니다 (또는 적어도 아무 일도하지 않아야합니다.
asm volatile ("")
또한 아무것도하지 않습니다.
asm ("" ::: "memory")
간단한 컴파일러 울타리입니다.
asm volatile ("" ::: "memory")
AFAIK는 이전과 동일합니다. volatile
키워드는이 조립 블록을 이동 할 수 없습니다 있다는 컴파일러를 알려줍니다. 예를 들어, 컴파일러가 모든 호출에서 입력 값이 동일하다고 결정하면 루프 밖으로 끌어 올릴 수 있습니다. 컴파일러가 배치를 최적화하기 위해 어셈블리에 대해 충분히 이해한다고 결정할 조건이 무엇인지 잘 모르겠지만 volatile
키워드는이를 완전히 억제합니다. 즉, 컴파일러 asm
가 선언 된 입력 또는 출력이없는 명령문 을 이동하려고 시도하면 매우 놀랄 것 입니다.
또한, volatile
그 출력 값이 사용되지 않는 것으로 결정하는 경우에도 발현을 삭제하는 컴파일러를 방지한다. 이것은 출력 값이있는 경우에만 발생할 수 있으므로 asm ("" ::: "memory")
.
단지에 대한 완전성에 대해 릴리 발라드의 대답 , 비주얼 스튜디오 2010 이벤트 _ReadBarrier()
, _WriteBarrier()
그리고 _ReadWriteBarrier()
(VS2010은 인라인 어셈블리 64 비트 응용 프로그램에 대한 허용하지 않습니다) 동일한 작업을 수행 할 수 있습니다.
이는 명령어를 생성하지 않지만 컴파일러의 동작에 영향을줍니다. 여기에 좋은 예가 있습니다 .
MemoryBarrier()
생성 lock or DWORD PTR [rsp], 0
'code' 카테고리의 다른 글
github를 JIRA에 어떻게 연결합니까? (0) | 2020.12.09 |
---|---|
PHP는 다른 네임 스페이스에서 모든 클래스를 가져 오는 방법 (0) | 2020.12.09 |
템플릿 정적 변수 (0) | 2020.12.09 |
Excel : 놀라운 축소 및 확장 컨트롤 (0) | 2020.12.09 |
C ++에서 클래스 범위 상수를 선언 / 정의 할 위치는 어디입니까? (0) | 2020.12.09 |