2015-01-20 65 views
2

我一直在閱讀這個主題,但是我一直沒有找到具體的答案來解決我的問題。我有興趣使用並行/多線程來提高我的遊戲性能,但我聽到了一些矛盾的事實。例如,多線程可能不會對遊戲的執行速度產生任何改進。我並行與線程 - 性能

我已經想到了兩種方法可以做到這一點:

  • 將呈現組件到一個線程。有一些事情 我需要改變,但我有一個好主意,需要做什麼 。
  • 使用openMP來並行渲染功能。我已經編寫了代碼,因此這可能更容易。

這是一個Uni評估,目標硬件是我的Uni計算機,它是多核(4核),因此我希望使用其中任何一種技術來獲得額外的效率。

因此,我的問題如下:我應該選擇哪一個?通常會產生最好的結果?

編輯:主要功能我的意思是並行/多線程遠:

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

你可以發佈你正在考慮多線程的代碼嗎? – 2015-01-20 23:23:30

+0

最好的結果取決於這些部件是如何並行化的,以及你梳理出並行性的能力,以便它可以被利用。沒有調查代碼就無法回答問題。 – 2015-01-20 23:29:34

+0

@MichaelB。它有點長,因爲它包含多種功能,但如果有必要,我會製作一個pastebin鏈接。 – MKII 2015-01-20 23:30:09

回答

2

,而不是調用的memcpy每個像素只考慮設定值出現。調用函數的開銷多次可能會佔據這個循環的總體執行時間。 E.g:

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; 
} 

你也可以避免有條件通過採用這裏avoiding conditionals提到的招數之一 - 在這樣一個緊密循環判斷條件可以是非常昂貴的。

編輯 - 至於是否是更好地同時運行ClipTransBlit的幾個實例或內部並行ClipTransBlit,我一般會說說話,最好在儘可能高的水平,可以實現並行化,以減少你招致的開銷通過設置它(創建線程,同步它們等)

在你的情況,但因爲它看起來像你正在繪製精靈,如果它們重疊然後沒有額外的同步你的高級線程可能會導致令人討厭的視覺工件,甚至是檢查alpha位的競爭條件。在這種情況下,低級並行可能是更好的選擇。

+0

我沒有看到任何方式可以每行調用一次,而無需執行其他會降低性能的其他任何操作。此外,這是渲染,我唯一處理圖形的時候是將視圖緩衝區寫入屏幕。 – MKII 2015-01-23 02:32:19

+0

@MKII我沒有注意到當alpha字節不爲零時你只寫入dest - 你可能仍然從刪除對memcpy的調用中受益,例如編輯 – gordy 2015-01-23 03:44:40

+0

我會花時間但我會打賭分支的成本比僅僅寫出不會被看到的代價更昂貴。如果您的源代碼中的大部分已知包含alpha,則可以實現一種算法,該算法將允許您跳過幀的大部分區域。 – rparolin 2015-01-23 05:26:08

0

從理論上講,它們應該產生相同的效果。實際上,這可能是完全不同的。

如果您打印出OpenMP程序的彙編代碼,則OpenMP只會在#pragma omp parallel ...範圍內調用某個函數。它類似於folk

OpenMP是面向並行計算的,另一方面,多線程更一般。例如,如果你想編寫一個GUI程序,多線程是必要的(有些框架可能會隱藏它,它仍然需要多線程)。但是,您從不想使用OpenMP來實現它。