programing

메모리 대역폭이 병목 현상이 되었는지 확인하는 방법은 무엇입니까?

oldcodes 2023. 7. 3. 23:09
반응형

메모리 대역폭이 병목 현상이 되었는지 확인하는 방법은 무엇입니까?

저는 매우 동시적인 C 프로그램을 진행하고 있는데, 코어 수가 8개 미만일 때는 잘 확장되지만, 8개 이상의 코어 확장은 거부합니다.

메모리 대역폭이 병목 현상인 것 같은데, 사실인지 확인하려면 어떻게 해야 합니까?

진단에 도움이 될 수 있는 도구/기술/OS 기능이 있습니까?

NUMA 96x8 코어 시스템에서 이 문제가 발생한 적이 있습니다.

문제의 90%는 메모리/캐시 동기화에 있습니다.동기화 루틴(아토믹, 뮤텍스)을 자주 호출하는 경우 모든 소켓에서 적절한 캐시 라인을 비활성화해야 하므로 전체 메모리 버스가 여러 사이클 동안 완전히 잠깁니다.

Intel VTune 또는 Perfuite같은 프로파일러를 실행하여 프로파일링하고 원자력에 걸리는 시간을 기록하도록 할 수 있습니다.만약 여러분이 그것들을 적절하게 사용하고 있다면, 그들은 10-40 사이클 사이의 무언가를 복용해야 합니다.최악의 경우 멀티스레드 애플리케이션을 8소켓(Intel Xeon의 8x8 코어)으로 확장할 때 300사이클이 발생했습니다.

또 다른 쉬운 프로파일링 단계는 아토믹/뮤텍스 없이 컴파일하여(코드가 허용하는 경우) 여러 소켓에서 실행하는 것입니다. 빠르게(잘못되었지만 빠르게) 실행됩니다.

코드가 8개 코어에서 빠르게 실행되는 이유는 사용자가 모두 동일한 물리적 칩(소켓)에 보관하는 한 Intel 프로세서가 아토믹을 실행할 때 캐시 잠금을 사용하기 때문입니다.잠금 장치가 메모리 버스로 가야 하는 경우 - 상황이 나빠지는 경우입니다.

제가 제안할 수 있는 유일한 것은 원자론/동기화 루틴을 얼마나 자주 부르는지 축소하는 것입니다.

내 지원서에 관해서는:코드를 하나의 소켓 이상으로 확장하기 위해 사실상 잠금이 없는 데이터 구조를 구현해야 했습니다.모든 스레드는 잠금이 필요한 작업을 축적하고 정기적으로 확인합니다. 이제는 그가 해당 작업을 플러시할 차례입니다.그런 다음 토큰을 전달하고 동기화 작업을 차례로 플러시합니다.분명히 기다리는 동안 할 일이 충분할 때만 효과가 있습니다.

+1 좋은 질문입니다.

먼저 고려해야 할 다른 요소들이 있습니다. 예를 들어 캐시 동기화 또는 원자 메모리 작업과 같은 불가피한 직렬화 부분은 병목 현상이 발생할 수 있으며 메모리 대역폭보다 확인하기 쉽습니다.

메모리 대역폭에 대해서는, 애플리케이션을 프로파일링하면서 메모리 대역폭을 소비하기 위해 단순한 데몬을 실행하는 것은 기본 메모리에 액세스하는 것을 반복하는 것입니다(캐시의 존재를 고려해야 합니다).데몬을 사용하여 사용하는 메모리 대역폭을 조정 및 기록하고 이 결과를 애플리케이션의 성능과 비교할 수 있습니다.

그렇게 엉성한 답변을 드려서 죄송합니다.할 수 있지만 XD.

편집: Linux에서 현재 사용 중인 메모리 대역폭을 측정하는 방법메모리 대역폭을 관찰하는 방법참조하십시오.

알고리즘과 플랫폼에 대한 더 많은 정보를 얻는 것이 도움이 될 수 있지만, 일반적으로 응용 프로그램이 확장되지 않는 여러 가지 이유가 있습니다.

  1. 명시적 동기화 사용(뮤텍스/토믹/트랜잭션 등): 병렬 프로그램에서의 동기화는 여러 스레드 간에 리소스를 공유해야 할 때 일부 순차적 섹션을 생성하는 것을 의미합니다.중요 섹션(원자력 작업은 실제로 매우 작은 중요 섹션)에 액세스하려는 스레드가 많을수록 경합이 많아지고 코어가 중요 섹션으로 돌아가므로 확장성이 제한됩니다.중요한 섹션의 크기를 줄이고 다른 데이터 구조/알고리즘을 선택하면 리소스를 사유화할 수 없는 경우 이러한 문제를 완화할 수 있습니다.

  2. 잘못된 공유: 두 개 이상의 스레드가 동일한 캐시 블록에 있는 관련 없는 개체를 공유합니다.일반적으로 응용프로그램을 한 코어에서 여러 소켓으로, 한 소켓에서 여러 소켓으로 확장할 때 캐시 누락이 증가함으로써 쉽게 탐지할 수 있습니다.일반적으로 데이터 구조를 캐시 블록 크기에 맞추면 문제가 해결됩니다.참고 항목: 잘못된 공유 제거 - Dobb

  3. 메모리 할당/할당 해제: 메모리 할당은 서로 다른 작업을 위한 메모리 청크를 제공하지만 할당 또는 할당 해제 시 경합이 발생할 수 있습니다.Intel TBB의 확장 가능할당자, Hoard 등과 같은 확장 가능한 스레드 세이프 메모리 할당자를 사용하여 해결할 수 있습니다.

  4. 유휴 스레드:당신의 알고리즘은 생산자/소비자 패턴을 가지고 있으며, 당신이 생산하는 것보다 더 빨리 소비하는 것이 가능합니까?데이터 크기가 충분히 커서 병렬화 비용을 상각하고 지역성을 잃음으로써 속도를 잃지 않습니까?당신의 알고리즘은 본질적으로 다른 이유로 확장이 불가능합니까?당신은 아마도 당신의 플랫폼과 알고리즘에 대해 우리에게 더 많은 것을 말해줘야 할 것입니다.Intel Advisor는 병렬화하는 가장 좋은 방법을 확인할 수 있는 적절한 도구입니다.

  5. 병렬 프레임워크: 무엇을 사용하고 있습니까?OpenMP, Intel TBB, 다른 것?순실?당신은 당신의 문제를 너무 많이 해결하거나 너무 많이 해결할 수 있습니까?런타임 자체가 확장 가능합니까?

  6. 다른 기술적 이유: 코어에 스레드를 잘못 바인딩하는 것(아마도 여러 스레드가 동일한 코어에 도달할 수 있음), 병렬 런타임의 기능(인텔의 OpenMP 런타임에 추가 스레드가 있음, 스레드를 코어에 바인딩하는 것은 메인 스레드와 동일한 코어에 이 추가 스레드를 매핑하여 하루를 망칠 수 있음) 등.

제 경험으로 볼 때, 위의 모든 것을 제거하면 메모리 대역폭을 의심하기 시작할 수 있습니다.메모리 대역폭이 제한 요인인지 알 수 있는 STREAM으로 쉽게 확인할 수 있습니다.Intel의 웹 사이트에는 메모리 대역폭 포화도를 감지하는 방법을 설명하는 이 기사가 있습니다.

위의 내용 중 어느 것도 결정적이지 않은 경우 일관성 프로토콜 트래픽 및/또는 NUMA(Non-Uniform Memory Access, mcqueue의 좋은 기사)로 인해 실제로 확장성이 제한될 수 있습니다.메모리의 일부 개체에 액세스할 때마다 캐시 무효화 요청을 생성하거나(무언가를 공유하고 캐시 일관성 프로토콜이 시작됨) 다른 소켓에 가까운 뱅크에 있는 메모리에 액세스합니다(프로세서 인터커넥트를 통과함).

언급URL : https://stackoverflow.com/questions/19238236/how-to-check-whether-memory-bandwidth-has-became-a-bottleneck

반응형