gpt4 book ai didi

multithreading - 通过设置亲和性在单核上运行多线程程序的性能?

转载 作者:行者123 更新时间:2023-12-04 23:29:15 25 4
gpt4 key购买 nike

简而言之:

在什么情况下在单核上运行多线程应用程序会破坏性能?

将多线程应用程序的关联设置为仅使用一个核心怎么样?

长:

我试图在它自己的线程上运行 2D 引擎的物理。它有效,起初性能似乎正常,但我决定让游戏尝试以 10K FPS 运行,物理以 120FPS 运行,进入任务管理器并将关联设置为程序只能使用一个核心的位置。

在将亲和性设置为一个核心之前,FPS 为 ~1700,之后变为 ~70FPS。没想到会有这么大的下降。我告诉游戏尝试以 300 FPS 和 60FPS 的物理速度运行。

同样的事情发生了。

我没有多想,就继续修改引擎。后来我改了一些绘图代码后再次测试,物理300 FPS,60FPS。所有内核都允许它管理 300FPS 就好了,与单核 FPS 的亲和力下降到 4。现在我知道在单核上运行多线程应用程序不可能那么糟糕,或者我不知道什么时候会发生您将亲和力设置为单个核心。

这是关于渲染/物理如何运行......

循环开始

收集输入直到 (1.0/FPS) 过去。

调用更新。

锁定物理线程互斥锁,因为游戏中的内容将使用物理数据,并且在此更新调用中的所有内容完成之前,我不希望引擎更新任何内容。

更新游戏中可能将 Draw 函数对象(保存要绘制的内容、绘制的位置、如何绘制)发送到渲染队列的所有内容。

解锁互斥锁。

渲染器对每个函数对象调用 operator() 并将它们从队列中删除。

更新画面。

重复循环。

物理线程循环:

    ALLEGRO_TIMER* timer(al_create_timer(1.0f / 60.0f));
double prevCount(0);

al_start_timer(timer);
while(true)
{
auto_mutex lock(m_mutex);

if(m_shutdown)
break;
if (!m_allowedToStep)
continue;
// Don't run too fast. This isn't final, just simple test code.
if (!(al_get_timer_count(timer) > prevCount))
continue;

prevCount = al_get_timer_count(timer);

m_world->Step(1.0f / 60.0f, 10, 10);
m_world->ClearForces();

}

//注意:Auto mutex 只是我创建的一个非常简单的对象,用于在构造函数中锁定互斥锁并在析构函数中解锁它。我正在使用 Allegro 5 的线程功能。

最佳答案

Under what scenarios can running a multithreaded app on a single core destroy performance?

What about setting the affinity of a multithreaded app to only use one core?


在这两种情况下,答案大致相同。如果您的程序在单核上运行,则一次仅运行一个线程。这意味着任何时候一个线程必须等待另一个线程,您都需要操作系统执行上下文切换,这是一项相当昂贵的操作。
当在多个内核上运行时,需要交互的两个线程很有可能同时运行,因此操作系统不需要为您的代码执行上下文切换。
所以真的,需要大量线程间同步的代码在单核上运行速度会变慢。
但是你可以让它变得更糟。
自旋锁或任何类型的忙等待循环绝对会破坏性能。原因应该很明显。您一次只能运行一个线程,因此如果您需要一个线程等待某个事件,您应该告诉操作系统立即将其置于 sleep 状态,以便另一个线程可以运行。
相反,如果您只是执行一些“while 条件不满足,继续循环”的忙循环,那么即使线程无关紧要,您也会保持线程运行。它会继续循环*直到操作系统决定它的时间到了,并调度另一个线程。 (如果线程没有被某些东西阻塞,它通常可以一次运行超过 10 毫秒。)
在一般的多线程编程中,*特别是在单核上运行的多线程代码,你需要玩得很好,不要过度占用 CPU 内核。如果您无事可做,请允许另一个线程运行。
并猜测您的代码在做什么。
你认为这些线条的作用是什么?
   if (!(al_get_timer_count(timer) > prevCount))
continue;
运行循环!
我准备好运行了吗?不?然后再次运行循环。我现在准备好运行了吗?仍然没有?再次运行循环......
换句话说,“我现在拥有 CPU,我永远不会屈服!如果有人想要 CPU,他们将不得不从我冰冷的尸体上拿走它!”
如果你没有什么可使用CPU的,那就放弃吧, 特别是如果您有另一个准备运行的线程。
使用互斥锁或其他一些同步原语,或者如果您可以使用更近似的基于时间的 sleep 周期,请调用 Sleep() .
但是,如果您想要任何体面的性能,请无限期地占用 CPU,如果您正在等待另一个线程进行一些处理。

关于multithreading - 通过设置亲和性在单核上运行多线程程序的性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7533415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com