수있는 기본 memory_order_seq_cst
대 (특히 memory_order_release
및 memory_order_acquire
뿐만 아니라 memory_order_consume
및 memory_order_relaxed
)을 완화 원자 연산을 사용하여 C11/C++ (11) 코드의 성능을 비교 한 벤치 마크 결과에 누군가 포인트는? 모든 아키텍처가 중요합니다. 미리 감사드립니다.C11/C++ 11 약한 메모리 벤치 마크
답변
이것은 최상의 솔루션이 아니지만 지금까지는 내 프로젝트 중 일부에서 벤치 마크 용으로 CDSChecker을 사용했습니다. 아직 완전한 프로그램에서는 사용하지 않았지만 독립된 유닛에서는 더 많이 사용했습니다.
CDSChecker는 정확성에 대한 철저한 테스트를 위해 벤치마킹 용으로 설계되지 않았습니다. CDSChecker는 코드의 성능에 대한 정보를 제공하지 않습니다. – briand
ARMv7에서 약간의 벤치마킹을 수행했습니다. 보고서의 경우 https://github.com/reinhrst/ARMBarriers, EuroLLVM의 내 슬라이드의 슬라이드 및 사용한 seqlock 코드를 참조하십시오.
단편 : seqlock 코드에서 Acquire/Release 기능은 순차적으로 일관된 버전보다 약 40 % 빠릅니다. 특정 코드 덩어리 (작업 훔치는 디큐)의 경우
기사가 아주 좋습니다. 반면에, sc와 acq-rel 사이의 차이는 제안 된 컴파일러가 제 자리를 지키기 때문에 위의 간격이 근본적으로 제거되기 때문에 (적어도이 예에서는) 게으른 컴파일로 인한 것입니다. – user2949652
나는 이것에 익숙해 진 이후로 꽤 오랜 시간이 걸렸지 만, sc와 acq-rel 사이의 차이점은 (이 예에서는) GitHub 레포에 언급 된 패치가 llvm에 추가되기 전에 컴파일러 최적화가 이루어지지 않았기 때문입니다. 이 예제에서 ARM 메모리 모델에서 acq-rel은 sc와 동일한 보증을 제공하기 때문입니다 (제공된 예제에서 ARM 메모리 모델, pre-llvm-patch). 나는 sc와 acq-rel이 일반적인 경우에 똑같이 빠르다 고 주장하고 싶지 않다. – Claude
, 나는 아주 좋은 SC-아토와 약한 아토와 C11 버전을 벤치 마크 paper 만 손에 최적화 된 어셈블리를 발견하고, 잘못된 버전은 완전히 이완 된 원자를 사용합니다. (우연히도 C11 버전에서는 앞서 언급 한 CDSChecker에서 버그가 발견되었습니다.) 비슷한 예를 환영합니다.
정확성만큼 성능이 중요하지 않습니다. 메모리 순서를 사용하여로드의 의미와 올바른 결과를 저장해야하며 3주기가 빠르기 때문에 다른 것을 사용하지 않아야합니다. OTOH, 단서가 없다면, 기본값보다 약간 느려질 수도 있지만 (종종 짝이 맞지는 않음) 올바른 것으로 보장됩니다. 부정확 한 "최적화 된"다중 스레드 코드보다 더 악몽 같은 것은 없습니다. – Damon
순차적으로 일관성있는 기본 메모리 정렬은 다른 어떤 것보다 엄격하므로 성능이 약한 정렬을 사용하는 유일한 이유입니다. 두 경우 모두 정확성에 대해 추론하는 방법을 알고 있지만 더 약한 순서에 대해서는 추론이 더 어렵습니다. 어쨌든 3주기의 문제가 아닙니다. 심지어 i7에서도 저장소 버퍼를 플러시하는 것은 일반적으로 수십 사이클 (오래된 프로세서에서는 훨씬 더 많습니다)이며 seq_cst와 ARM에서의 소비는 훨씬 더 큽니다. – user2949652
벤치 마크에서 의미있는 결과를 얻는 것은 거의 불가능합니다. 단일로드/저장소는 신뢰할 수있는 방법으로 거의 측정 할 수 없습니다. 동기화없이 동일한 값 (또는 값 집합)을 여러 번로드 및 저장하면 캐시 스 래싱 만 벤치마킹되지만 실제 작업은 벤치마킹되지 않습니다. 동기화는 ~ 1000X 더 비싸지는 동기화 프리미티브를 측정합니다. 그건, 그리고 당신은 정말로 선택의 여지가 있지만 올바른 코드를 작성합니다. 일부 데이터에 대한 보장이 있기 전에 상황이 필요하다면 더 빠를 수 있기 때문에 빠져 나올 수 없습니다. – Damon