2015-01-20 4 views
2

나는이 주제에 대해 읽었지만 내 질문에 대한 구체적인 답을 찾을 수 없었다. 필자는 게임의 성능을 향상시키기 위해 병렬 처리/멀티 스레딩을 사용하는 것에 관심이 있지만 몇 가지 모순되는 사실을 들었습니다. 예를 들어, 멀티 스레딩은 게임의 실행 속도를 향상시키지 못할 수 있습니다.병렬 처리 대 스레딩 - 성능

  • 스레드로 렌더링 구성 요소를 넣어 : 나는

    나는이 두 가지 방법을 생각했다. 몇 가지가 있습니다. 변경해야하지만, 어떤 것이 좋을지에 대해서는 잘 알고 있습니다. 완료.

  • OpenMP를 사용하여 렌더링 기능을 병렬 처리합니다. 이미 그렇게하기위한 코드가 있으므로 더 쉬운 옵션 일 수 있습니다.

이것은 Uni 평가이므로 대상 하드웨어는 멀티 코어 (4 코어) 인 Uni의 컴퓨터이므로 이러한 기술 중 하나를 사용하여 몇 가지 추가 효율성을 얻으려고합니다.

제 질문은 다음과 같습니다. 어느 것을 선호합니까? 어느 것이 보통 가장 좋은 결과를 산출합니까?

편집 :

void Visualization::ClipTransBlit (int id, Vector2i spritePosition, FrameData frame, View *view) 
{ 
    const Rectangle viewRect = view->GetRect(); 
    BYTE *bufferPtr = view->GetBuffer(); 

    Texture *txt = txtMan_.GetTexture (id); 
    Rectangle clippingRect = Rectangle (0, frame.frameSize.x, 0, frame.frameSize.y); 

    clippingRect.Translate (spritePosition); 
    clippingRect.ClipTo (viewRect); 
    Vector2i negPos (-spritePosition.x, -spritePosition.y); 
    clippingRect.Translate (negPos); 

    if (spritePosition.x < viewRect.left_) { spritePosition.x = viewRect.left_; } 
    if (spritePosition.y < viewRect.top_) { spritePosition.y = viewRect.top_; } 

    if (clippingRect.GetArea() == 0) { return; } 

    //clippingRect.Translate (frameData); 

    BYTE *destPtr = bufferPtr + ((abs(spritePosition.x) - abs(viewRect.left_)) + (abs(spritePosition.y) - abs(viewRect.top_)) * viewRect.Width()) * 4; // corner position of the sprite (top left corner) 
    BYTE *tempSPtr = txt->GetData() + (clippingRect.left_ + clippingRect.top_ * txt->GetSize().x) * 4; 

    int w = clippingRect.Width(); 
    int h = clippingRect.Height(); 
    int endOfLine = (viewRect.Width() - w) * 4; 
    int endOfSourceLine = (txt->GetSize().x - w) * 4; 

    for (int i = 0; i < h; i++) 
    { 
     for (int j = 0; j < w; j++) 
     { 
      if (tempSPtr[3] != 0) 
      { 
       memcpy(destPtr, tempSPtr, 4); 
      } 

      destPtr += 4; 
      tempSPtr += 4; 
     } 

     destPtr += endOfLine; 
     tempSPtr += endOfSourceLine; 
    } 

} 대신이 값을 설정하는 것이 좋습니다 각각의 픽셀에 대한 방어 적이기를 호출

+0

멀티 스레딩을 고려중인 코드를 게시 할 수 있습니까? –

+0

최상의 결과는 파트가 병렬화 될 수있는 방법과 병렬 처리를 활용하여 활용할 수있는 능력에 따라 다릅니다. 코드를 조사하지 않고도 질문에 답할 수는 없습니다. –

+0

@MichaelB. 그것은 여러 기능을 포함하고 있기 때문에 약간 길지만, 필요한 경우 나는 pastebin 링크를 만들 것입니다. – MKII

답변

2

: 내 말은 주요 기능이 떨어져/멀티 스레드를 병렬 처리합니다. 여러 번 함수를 호출 할 때 오버 헤드가이 루프의 전체 실행 시간을 지배 할 수 있습니다. 예컨대 : 당신이 여기 avoiding conditionals 언급 한 트릭 중 하나를 사용하여 조건을 피할 수

for (int i = 0; i < h; i++) 
{ 
    for (int j = 0; j < w; j++) 
    { 
     if (tempSPtr[3] != 0) 
     { 
      *((DWORD*)destPtr) = *((DWORD*)tempSPtr); 
     } 

     destPtr += 4; 
     tempSPtr += 4; 
    } 

    destPtr += endOfLine; 
    tempSPtr += endOfSourceLine; 
} 

- 같은 꽉 루프 조건문에 매우 비쌀 수 있습니다.

편집 - 그것은 동시에 ClipTransBlit의 여러 인스턴스를 실행하거나 내부적으로 ClipTransBlit을 병렬화하는 것이 좋습니다 여부에 , 나는 당신이 발생하는 오버 헤드를 줄이기 위해 가능한 한 높은 수준의 병렬 처리를 구현하는 것이 좋습니다 말하기 일반적으로 말할 것 (스레드 만들기, 동기화 등)

당신이 스프라이트를 그리는 것처럼 보일 수도 있지만, 추가 동기화없이 오버랩하면 높은 수준의 스레딩으로 인해 불쾌한 시각적 효과가 발생할 수 있습니다. 아티팩트 및 심지어 알파 비트 검사시 경쟁 조건이 있습니다. 이 경우 저수준 병렬 처리가 더 나은 선택 일 수 있습니다.

+0

어쨌든 성능을 저하시키는 다른 작업을 수행하지 않고 한 줄에 한 번 호출하는 방법은 없습니다. 또한, 이것은 렌더링입니다. 그래픽을 다루는 유일한 다른 시각은 화면에 뷰 버퍼를 쓸 때입니다. – MKII

+0

@MKII 알파 바이트가 0이 아닌 경우에만 dest에 쓰는 것을 알지 못했습니다. memcpy에 대한 호출을 제거해도 도움이 될 수 있습니다. 예를 들어 편집 중 – gordy

+0

시간이 좀 걸리지 만, 지점의 비용은 볼 수없는 글을 쓰는 것보다 비용이 많이 듭니다. 소스의 큰 섹션이있는 경우 프레임의 큰 섹션을 건너 뛰는 것을 건너 뛸 수있는 알고리즘을 구현할 수있는 알파가 포함되어있는 것으로 알려져 있습니다. – rparolin

0

이론적으로, 그들은 동일한 효과를 가져야한다. 실제로는 상당히 다를 수 있습니다.

OpenMP 프로그램의 어셈블리 코드를 인쇄하면 OpenMP는 #pragma omp parallel ...과 같은 범위의 일부 함수를 호출합니다. folk과 유사합니다.

OpenMP는 병렬 처리 지향적이며 다른 한편으로는 멀티 스레드가 더 일반적입니다. 예를 들어, GUI 프로그램을 작성하려면 멀티 스레드가 필요합니다 (일부 프레임 워크는이를 숨길 수 있지만 여전히 다중 스레드가 필요합니다). 그러나 OpenMP로이를 구현하고 싶지는 않습니다.