__asm____volatile__는 C에서 무엇을 합니까?
C코드 몇 개를 조사해 봤는데
http://www.mcs.anl.gov/~httputomo/rdtsc.http://http://www.mcs.anl.gov/
이런 걸 쓰는데__inline__,__asm__다음과 같은 경우:
코드 1:
static __inline__ tick gettick (void) {
unsigned a, d;
__asm__ __volatile__("rdtsc": "=a" (a), "=d" (d) );
return (((tick)a) | (((tick)d) << 32));
}
코드2:
volatile int __attribute__((noinline)) foo2 (int a0, int a1) {
__asm__ __volatile__ ("");
}
code1과 code2는 어떤 역할을 하나요?
(편집자 주: 이 특정 RDTSC 사용 사례에서는 다음 기능을 사용하는 것이 좋습니다.C++에서 x86_64의 CPU 사이클 카운트를 얻는 방법https://gcc.gnu.org/wiki/DontUseInlineAsm) 도 참조해 주세요.
그__volatile__의 수식어__asm__block은 컴파일러의 옵티마이저가 코드를 그대로 실행하도록 강제합니다.이 기능이 없으면 옵티마이저는 완전히 삭제하거나 루프에서 꺼내 캐싱할 수 있다고 생각할 수 있습니다.
이것은, 에 도움이 됩니다.rdtsc다음과 같은 지시:
__asm__ __volatile__("rdtsc": "=a" (a), "=d" (d) )
이것은 의존 관계가 없기 때문에 컴파일러는 값을 캐시할 수 있다고 생각할 수 있습니다.Volatile은 새로운 타임스탬프를 읽도록 강제하기 위해 사용됩니다.
단독으로 사용하는 경우는, 다음과 같습니다.
__asm__ __volatile__ ("")
실제로는 아무것도 실행되지 않습니다.다만, 메모리 액세스 명령의 순서를 변경할 수 없는 컴파일 타임 메모리 장벽을 취득할 수 있습니다.
__asm__ __volatile__ ("":::"memory")
그rdtscinstruction은 휘발성의 좋은 예입니다. rdtsc는 보통 일부 명령을 실행하는 데 걸리는 시간을 재야 할 때 사용됩니다.이런 코드를 상상해보세요. 시간을 재려면r1그리고.r2의 실행:
__asm__ ("rdtsc": "=a" (a0), "=d" (d0) )
r1 = x1 + y1;
__asm__ ("rdtsc": "=a" (a1), "=d" (d1) )
r2 = x2 + y2;
__asm__ ("rdtsc": "=a" (a2), "=d" (d2) )
여기서 컴파일러는 실제로 타임스탬프를 캐시할 수 있습니다.유효한 출력은 각 행이 실행하는 데 정확히0 클럭이 소요되었음을 나타낼 수 있습니다.분명히 이건 네가 원하는 게 아니야 그래서 네가 소개한 거야__volatile__캐시를 방지하려면:
__asm__ __volatile__("rdtsc": "=a" (a0), "=d" (d0))
r1 = x1 + y1;
__asm__ __volatile__("rdtsc": "=a" (a1), "=d" (d1))
r2 = x2 + y2;
__asm__ __volatile__("rdtsc": "=a" (a2), "=d" (d2))
이제 매번 새로운 타임스탬프가 표시되지만 컴파일러와 CPU 모두 이러한 문장의 순서를 변경할 수 있다는 문제가 있습니다.r1과 r2가 이미 계산된 후에 asm 블록을 실행할 수 있습니다.이 문제를 해결하려면 , 시리얼화를 강제하는 몇개의 장벽을 추가합니다.
__asm__ __volatile__("mfence;rdtsc": "=a" (a0), "=d" (d0) :: "memory")
r1 = x1 + y1;
__asm__ __volatile__("mfence;rdtsc": "=a" (a1), "=d" (d1) :: "memory")
r2 = x2 + y2;
__asm__ __volatile__("mfence;rdtsc": "=a" (a2), "=d" (d2) :: "memory")
주의:mfenceCPU 측 장벽을 적용하는 명령과 컴파일 시간 장벽을 적용하는 휘발성 블록의 "메모리" 지정자를 지정합니다.최신 CPU에서는mfence:rdtsc와 함께rdtscp좀 더 효율적인 방법으로요.
asmC 소스 코드에 네이티브어셈블리 코드를 포함하기 위한 것입니다.예.
int a = 2;
asm("mov a, 3");
printf("%i", a); // will print 3
컴파일러에는 다양한 종류가 있습니다. __asm__는 컴파일러 고유의 차이와 동의어여야 합니다.
volatile변수를 외부에서 변경할 수 있음을 의미합니다(C 프로그램에 의해 변경되지 않음).를 들어, 주소가 「」인 마이크로 하는 경우.0x0000x1234는 디바이스 고유의 인터페이스에 매핑됩니다(즉, GameBoy를 코딩할 때는 버튼/화면 등에 액세스합니다).
volatile std::uint8_t* const button1 = 0x00001111;
에 의해, 「」에 의존하는 컴파일러의 가 되었습니다.*button1코드에 의해 변경되지 않는 한 변경되지 않습니다.
또한 변수가 다른 스레드에 의해 수정될 수 있는 멀티 스레드 프로그래밍(현재는 필요 없음?)에서도 사용됩니다.
inline는 컴파일러가 함수를 호출하도록 하는 힌트입니다.
inline int f(int a) {
return a + 1
}
int a;
int b = f(a);
은 함수 할 수 .f, 하하에int b = a + 1마치f는 함수의 사용 이나 내용에 됩니다.대부분의 컴파일러는 기능 사용률/내용에 따라 자동으로 최적화됩니다. __inline__이 예에서는 보다 구체적인 의미가 있을 수 있습니다.
로 ★★★★★★★★★★★★★★★」__attribute__((noinline))(GCC 고유의 구문)에 의해 함수의 인라인화가 방지됩니다.
__asm__합니다.
__volatile__으로 임베디드수식자는 컴파일러 에 관한 합니다.status register★★★★★★★★★★★★★★★★의 경우ERROR ★★★★★★★★★★★★★★★★★」READY비트 때문에 최적화 중에 문제가 발생합니다. __volatile__는 오브젝트가 빠르게 변경될 수 있음을 컴파일러에게 알리고 오브젝트의 모든 참조가 진정한 참조가 되도록 하기 위한 방법으로 도입되었습니다.
언급URL : https://stackoverflow.com/questions/26456510/what-does-asm-volatile-do-in-c
'programing' 카테고리의 다른 글
| PHP: 원래 문자 집합을 모르는 상태에서 문자열을 UTF-8로 변환하거나 최소한 시도해 보십시오. (0) | 2022.10.22 |
|---|---|
| .jar 파일의 클래스를 사용하는 방법 (0) | 2022.10.22 |
| 어레이에 여러 요소가 있는지 확인하는 더 좋은 방법은 무엇입니까? (0) | 2022.10.21 |
| MariaDB Galera Cluster와 함께 사용할 경우 PHPUnit 테스트가 랜덤으로 실패함(읽기/쓰기 사용자) (0) | 2022.10.21 |
| Linux에서 rand()가 Mac보다 훨씬 더 자주 숫자를 반복하는 이유는 무엇입니까? (0) | 2022.10.21 |