并行与线程 - 性能

Parallelism vs Threading - Performance

我一直在阅读有关该主题的内容,但未能找到我的问题的具体答案。我有兴趣使用 parallelism/multithreading 来提高我的游戏性能,但我听到了一些相互矛盾的事实。例如,多线程可能不会对游戏的执行速度产生任何改进。我

我想到了两种方法:

这是一个 Uni 评估,目标硬件是我的 Uni 计算机,它们是多核(4 核),因此我希望使用其中任何一种技术来提高效率。

因此,我的问题如下:我应该选择哪一个?哪个通常会产生最好的结果?

编辑:主要功能我的意思是 parallelize/multithread 离开:

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

}

与其为每个像素调用 memcpy,不如考虑只在此处设置值。多次调用函数的开销可能会支配此循环的整体执行时间。例如:

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 位时出现竞争条件。在那种情况下,低级并行性可能是更好的选择。

理论上,它们应该产生相同的效果。实际上,它可能完全不同。

如果您打印出 OpenMP 程序的汇编代码,OpenMP 只是调用范围内的一些函数,如 #pragma omp parallel ...。它类似于 folk.

OpenMP是面向并行计算的,另一方面,多线程更通用。 比如你要写一个GUI程序,多线程是必须的(有些框架可能隐藏了,还是需要多线程)。但是,您永远不想使用 OpenMP 来实现它。