IT이야기

언제 cudaDeviceSynchronize를 호출

cyworld 2021. 10. 23. 09:51
반응형

언제 cudaDeviceSynchronize를 호출합니까?


cudaDeviceSynchronize함수 호출이 실제로 필요한 경우는 언제 입니까?

내가 CUDA 문서에서 이해하는 한 CUDA 커널은 비동기식이므로 cudaDeviceSynchronize각 커널 실행 후에 호출해야 하는 것 같습니다 . 그러나 cudaDeviceSynchronize시간 측정 이전의 코드를 제외하고 는 동일한 코드(신경망 훈련)를 사용하거나 사용하지 않고 시도했습니다 . 동일한 결과를 얻었지만 속도는 7-12x(매트릭스 크기에 따라 다름)입니다.

따라서 cudaDeviceSynchronize시간 측정과 별도로 사용할 이유가 있는지 여부가 문제입니다 .

예를 들어:

  • 를 사용하여 GPU에서 호스트로 데이터를 다시 복사하기 전에 필요 cudaMemcpy합니까?

  • 다음과 같은 행렬 곱셈을 수행하면

    C = A * B
    D = C * F
    

cudaDeviceSynchronize사이에 넣어야 하나요?

내 실험에서 나는 그렇지 않은 것 같습니다.

cudaDeviceSynchronize프로그램이 왜 그렇게 느려지나요?


CUDA 커널 실행은 비동기식이지만 하나의 스트림(기본 동작)에 배치된 모든 GPU 관련 작업은 순차적으로 실행됩니다.

예를 들어,

kernel1<<<X,Y>>>(...); // kernel start execution, CPU continues to next statement
kernel2<<<X,Y>>>(...); // kernel is placed in queue and will start after kernel1 finishes, CPU continues to next statement
cudaMemcpy(...); // CPU blocks until memory is copied, memory copy starts only after kernel2 finishes

따라서 귀하의 예에서는 가 필요하지 않습니다 cudaDeviceSynchronize. 그러나 어떤 커널이 오류를 일으켰는지 감지하기 위해 디버깅에 유용할 수 있습니다(있는 경우).

cudaDeviceSynchronize속도가 느려질 수 있지만 7-12x는 너무 많은 것 같습니다. 시간 측정에 문제가 있거나 커널이 정말 빠르며 명시적 동기화의 오버헤드가 실제 계산 시간에 비해 클 수 있습니다.


사용 cudaDeviceSynchronize()이 적절한 한 가지 상황 은 여러 cudaStream대가 실행 중이고 일부 정보를 교환하도록 하려는 경우입니다. 이에 대한 실제 사례는 양자 몬테카를로 시뮬레이션의 병렬 템퍼링입니다. 이 경우 우리는 모든 스트림이 일련의 명령 실행을 완료하고 서로에게 메시지를 전달하기 시작하기 전에 일부 결과를 얻었는지 확인하고 싶습니다. 그렇지 않으면 결국 가비지 정보를 전달하게 됩니다. 이 명령을 사용하는 이유는 프로그램이 너무 느려지기 때문입니다.cudaDeviceSynchronize()계속하기 전에 장치의 모든 스트림에서 이전에 실행된 모든 명령을 기다리도록 프로그램을 강제 실행합니다(CUDA C 프로그래밍 가이드에서). 말했듯이 커널 실행은 일반적으로 비동기식이므로 GPU 장치가 커널을 실행하는 동안 CPU는 기다리지 않고 계속해서 다른 명령을 수행하고 장치에 더 많은 명령을 내릴 수 있습니다. 그러나 이 동기화 명령을 사용하면 CPU는 다른 작업을 수행하기 전에 모든 GPU 작업이 완료될 때까지 강제로 유휴 상태가 됩니다. 이 동작은 장치 코드의 비동기 실행(하나의 스트림이든 여러 스트림이든)으로 인해 "임의의" 시간에 발생하는 segfault가 있을 수 있으므로 디버깅할 때 유용합니다.cudaDeviceSynchronize() 계속하기 전에 프로그램이 스트림의 커널/memcpy가 완전한지 확인하도록 하여 불법 액세스가 발생하는 위치를 쉽게 찾을 수 있습니다(동기화 중에 오류가 표시되기 때문에).


GPU가 일부 데이터 처리를 시작하도록 하려면 일반적으로 커널 호출을 수행합니다. 그렇게 하면 장치(GPU)가 지시한 대로 작업을 시작합니다. 그러나 호스트의 일반 순차 프로그램과 달리 CPU(CPU)는 계속해서 프로그램의 다음 코드 라인을 실행합니다. cudaDeviceSynchronize는 호스트(CPU)가 장치(GPU)가 시작한 모든 스레드의 실행을 마칠 때까지 기다리게 하므로 프로그램은 정상적인 순차 프로그램인 것처럼 계속됩니다.

작고 간단한 프로그램에서는 일반적으로 GPU를 사용하여 계산을 수행할 때 cudaDeviceSynchronize를 사용하여 결과를 요청하는 CPU와 계산을 완료하는 GPU 간의 타이밍 불일치를 방지합니다. cudaDeviceSynchronize를 사용하면 프로그램을 훨씬 쉽게 코딩할 수 있지만 한 가지 주요 단점이 있습니다. CPU는 항상 유휴 상태이고 GPU는 계산을 수행합니다. 따라서 고성능 컴퓨팅에서는 GPU가 완료될 때까지 기다리는 동안 CPU가 연산을 수행하도록 하는 경우가 많습니다.

ReferenceURL : https://stackoverflow.com/questions/11888772/when-to-call-cudadevicesynchronize

반응형