programing

성능 손실을 감수하면서 'if' 문으로 두 개의 유사한 커널을 통합해야 합니까?

newstyles 2023. 10. 26. 20:49

성능 손실을 감수하면서 'if' 문으로 두 개의 유사한 커널을 통합해야 합니까?

저는 코드가 거의 비슷하지만 약간의 차이가 있다는 의미에서 2개의 매우 유사한 커널 기능을 가지고 있습니다.현재 두 가지 옵션이 있습니다.

  • 두 가지 다른 방법을 작성합니다(단, 매우 유사한 방법).
  • 하나의 커널을 작성하고 if/else 문에 다른 코드 블록을 넣습니다.

if 문이 알고리즘 성능에 얼마나 영향을 줄까요?
모든 블록의 모든 스레드가 if 또는 다른 것으로 들어가기 때문에 분기가 없다는 것을 알고 있습니다.
그렇다면 커널 함수가 많이 호출되면 if 문 하나로 인해 성능이 저하되는 것입니까?

세 번째 대안은 C++ 템플릿을 사용하고 if/switch 문에 사용되는 변수를 템플릿 매개 변수로 만드는 것입니다.필요한 커널의 각 버전을 인스턴스화하면 컴파일러가 데드 코드와 분기를 최적화하기 때문에 분기 분산이나 조건부 평가 없이 여러 커널이 서로 다른 작업을 수행하게 됩니다.

아마도 이런 것들이 있을 것입니다.

template<int action>
__global__ void kernel()
{
    switch(action) {
       case 1:
       // First code
       break;

       case 2:
       // Second code
       break;
    }
}

template void kernel<1>();
template void kernel<2>();

명령 문제 슬롯을 자주 낭비하게 되므로 성능이 약간 저하됩니다. 특히 내부 루프에 있는 경우에는 성능이 저하됩니다. 하지만 워프가 발산하는 것만큼 성능이 저하되지는 않습니다.

하지만 큰 문제라면 루프 밖으로 조건을 옮기는 것이 가치가 있을지도 모릅니다.그러나 경사가 정말로 발산적이라면 분기를 제거하는 방법에 대해 생각해 보십시오. 예를 들어, 대신에

if (i>0) {
    x = 3;
} else {
    x = y;
}

해라

x = ((i>0)*3) | ((i<3)*y);

언급URL : https://stackoverflow.com/questions/6179295/should-i-unify-two-similar-kernels-with-an-if-statement-risking-performance-l