简而言之:
在什么情况下,在单核上运行多线程应用会破坏性能?
如果将多线程应用程序的亲和性设置为只使用一个内核呢?
在long中:
我试着在2D引擎自己的线程上运行它的物理特性。它可以工作,一开始性能似乎很正常,但我决定告诉游戏尝试以10K FPS运行,物理运行在120FPS,进入任务管理器并设置亲和力,程序只能使用一个内核。
在设置到一个核心的亲和力之前,FPS为~1700,之后为~70FPS。我没想到会有这样的下降。我告诉游戏运行速度为300fps,物理速度为60FPS。
同样的事情也发生了。
我没有考虑太多,所以我只是继续修改引擎。在修改了一些绘图代码后,我再次测试了它,300fps,60FPS的物理。在允许所有内核的情况下,它可以很好地管理300FPS,与单核FPS的亲和力下降到4。现在我知道在单核上运行多线程应用程序不可能那么糟糕,或者我不知道当您将亲和力设置为单核时会发生什么。
这是关于渲染/物理如何运行的。
循环开始
收集输入,直到(1.0 / FPS)通过。
调用update。
锁定物理线程互斥,因为游戏中的东西将使用物理数据,我不想让引擎更新任何东西,直到这个update调用中的所有东西都完成。
更新游戏中可能发送绘制函数对象(保存绘制内容,绘制位置,如何绘制)到渲染队列的所有内容。
解锁互斥锁。
渲染器在每个函数对象上调用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();
}//注意:自动互斥锁只是我创建的一个非常简单的对象,用于在构造函数中锁定互斥锁,并在析构函数中解锁。我使用的是Allegro 5的线程函数。
发布于 2011-09-24 04:48:02
在什么情况下,在单核上运行多线程应用会破坏性能?
如果将多线程应用程序的亲和性设置为只使用一个内核呢?
在这两种情况下,答案基本相同。如果你的程序在一个内核上运行,那么一次只有一个线程运行。这意味着,每当一个线程必须等待另一个线程时,您需要操作系统执行上下文切换,这是一个相当昂贵的操作。
当在多核上运行时,需要交互的两个线程很有可能同时运行,因此操作系统不需要执行上下文切换即可继续执行代码。
因此,实际上,需要大量线程间同步的代码在单核上的运行速度会更慢。
但你可以让事情变得更糟。自旋锁或任何类型的忙碌等待循环都会完全破坏性能。原因应该是显而易见的。您一次只能运行一个线程,因此如果您需要一个线程等待某个事件,您应该告诉操作系统立即将其置于休眠状态,以便另一个线程可以运行。
如果你只是做了一些“虽然条件不满足,保持循环”的繁忙循环,你保持线程运行,即使它没有做任何事情。它将继续循环*,直到操作系统决定它的时间到了,并且它调度另一个线程。(如果线程没有被某些东西阻塞,它通常会被允许一次运行10毫秒以上。)
在一般的多线程编程中,尤其是在单核上运行的多线程代码中,你需要表现得很好,而不是在必要的情况下占用CPU核心。如果你没有什么可做的,允许另一个线程运行。
猜猜你的代码在做什么。
你认为这些线条的效果是什么?
if (!(al_get_timer_count(timer) > prevCount))
continue;运行循环!我准备好跑了吗?不是吗?然后再次运行循环。我现在可以跑了吗?还是没有?再次运行循环.....
换句话说,“我现在有了CPU,我永远不会投降!如果其他人想要CPU,他们就必须从我冰冷的身体上拿走它!”
如果你没有什么可以使用的CPU,那就放弃它,如果你有另一个准备运行的线程,尤其是。
使用互斥或其他一些同步原语,或者如果您可以使用更近似的基于时间的休眠周期,则调用Sleep()。
但是,如果你想要任何一种不错的性能,如果你在等待另一个线程来做一些处理,不要无限期地占用CPU。
发布于 2011-09-24 02:54:46
当你看处理器的时候,不要把它看作一个计算一件事情接着一件事情的块。把它看作是一个计算器,你必须为它预留一个时间
Windows (和所有操作系统)确保为所有正在运行的应用程序保留此时间。当你运行一个程序时,计算机并不只是做新程序想要的所有计算,windows会给程序分配一段特定的时间。当该时间结束时,下一个程序将获得一些时间。windows为您完成了所有这些工作,因此只有当您想要了解它时,它才是相关的。
这确实会影响你看待多线程的方式,因为当windows环顾四周,看到一个多线程的应用程序时,它会说“我将把它作为两个独立的程序来处理”,所以它会为这两个程序分配时间。因此,其中一个不会完全阻止另一个进行计算。
所以,多线程运行不会降低程序的性能,但会使周围的其他程序变得更慢。并产生少量的开销。但是,如果您正在进行大型计算,并且这会导致您的程序挂起,那么可以自由地使用多线程。
https://stackoverflow.com/questions/7533415
复制相似问题