programing

GCC 메모리 장벽 __sync_synchronize vs asm volatile("") ::"memory")

firstcheck 2022. 7. 23. 11:24
반응형

GCC 메모리 장벽 __sync_synchronize vs asm volatile("") ::"memory")

asm volatile("": : :"memory")는 메모리 장벽으로 자주 사용됩니다(예를 들어 Linux 커널에서 볼 수 있습니다).barrier매크로)

이것은 GCC 빌트인의 동작과 비슷합니다.

이 둘은 비슷한가요?

그렇지 않은 경우, 어떤 차이가 있으며, 어떤 경우에 다른 하나를 사용할 수 있습니까?

큰 차이가 있습니다.첫 번째 옵션(인라인 asm)은 실행 시 실제로 아무것도 하지 않습니다.명령어는 실행되지 않으며 CPU는 이를 인식하지 못합니다.컴파일러가 최적화의 일부로서 이 포인트(어떤 방향으로든)를 넘어 부하나 스토어를 이동하지 않도록 하기 위해서 컴파일시에만 기능합니다.SW 장벽이라고 합니다.

두 번째 장벽(내장 동기)은 단순히 하드웨어 장벽으로 해석됩니다.x86 또는 다른 아키텍처에서는 펜스(mfence/sfence) 운용이 가능합니다.CPU는 실행 시 다양한 최적화를 실행할 수도 있습니다.가장 중요한 것은 실제로 순서가 어긋난 동작을 실행하는 것입니다.이 명령에서는 부하나 저장소가 이 포인트를 통과할 수 없도록 동기 포인트의 올바른 쪽에서 감시해야 합니다.

여기 또 다른 좋은 설명이 있습니다.

메모리 장벽의 종류

위에서 설명한 바와 같이 컴파일러와 프로세서 모두 메모리 장벽을 사용해야 하는 방식으로 명령 실행을 최적화할 수 있습니다.컴파일러와 프로세서 양쪽에 영향을 미치는 메모리 장벽은 하드웨어 메모리 장벽이며 컴파일러에만 영향을 미치는 메모리 장벽은 소프트웨어 메모리 장벽입니다.

메모리 장벽은 하드웨어 및 소프트웨어 메모리 장벽과 더불어 메모리 읽기, 메모리 쓰기 또는 둘 다로 제한될 수 있습니다.읽기 및 쓰기 모두에 영향을 미치는 메모리 장벽은 완전한 메모리 장벽입니다.

멀티프로세서 환경 특유의 메모리 장벽도 있습니다.이러한 메모리 장벽의 이름 앞에는 "smp"가 붙습니다.멀티프로세서 시스템에서는 이러한 장벽이 하드웨어 메모리 장벽이며 유니프로세서 시스템에서는 소프트웨어 메모리 장벽입니다.

barrier() 매크로는 유일한 소프트웨어 메모리 장벽이며 완전한 메모리 장벽입니다.Linux 커널의 다른 메모리 장벽은 모두 하드웨어 장벽입니다.하드웨어 메모리 장벽은 암시적인 소프트웨어 장벽입니다.

소프트웨어 장벽이 유용한 경우의 예: 다음 코드를 고려하십시오.

for (i = 0; i < N; ++i) {
    a[i]++;
}

최적화와 함께 컴파일된 이 단순한 루프는 대부분 전개되고 벡터화됩니다.다음은 어셈블리 코드 gcc 4.8.0 -O3 generated packed(벡터) 연산입니다.

400420:       66 0f 6f 00             movdqa (%rax),%xmm0
400424:       48 83 c0 10             add    $0x10,%rax
400428:       66 0f fe c1             paddd  %xmm1,%xmm0
40042c:       66 0f 7f 40 f0          movdqa %xmm0,0xfffffffffffffff0(%rax)
400431:       48 39 d0                cmp    %rdx,%rax
400434:       75 ea                   jne    400420 <main+0x30>

단, 각 반복에 인라인어셈블리를 추가할 때 gcc는 장벽을 통과하는 동작의 순서를 변경할 수 없으므로 gcc는 이들을 그룹화할 수 없으며 어셈블리는 루프의 스칼라 버전이 됩니다.

400418:       83 00 01                addl   $0x1,(%rax)
40041b:       48 83 c0 04             add    $0x4,%rax
40041f:       48 39 d0                cmp    %rdx,%rax
400422:       75 f4                   jne    400418 <main+0x28>

단, CPU가 이 코드를 실행할 때 메모리 주문 모델이 파손되지 않는 한 "후드 아래에서" 작업을 재주문할 수 있습니다.즉, 조작을 정상적으로 실행할 수 없습니다(CPU가 이를 서포트하고 있는 경우는, 현재 대부분의 조작이 서포트하고 있습니다.하드웨어 울타리가 있었다면 그걸 막을 수 있었을 거예요.

SW만의 장벽의 유용성에 대한 코멘트:

일부 마이크로 컨트롤러 및 기타 임베디드 플랫폼에서는 멀티태스킹이 가능하지만 캐시 시스템이나 캐시 지연이 없기 때문에 하드웨어 장벽 명령이 없습니다.그래서 SW 스핀락 같은 걸 해야 돼요.소프트웨어 장벽은 이러한 알고리즘에서 컴파일러의 최적화(읽기/쓰기 조합 및 순서 변경)를 방지합니다.

언급URL : https://stackoverflow.com/questions/19965076/gcc-memory-barrier-sync-synchronize-vs-asm-volatile-memory

반응형