【发布时间】:2012-06-20 21:59:15
【问题描述】:
背景: 我希望我的问题不是太含糊。我会尽量解释,不能贴太多代码,因为受影响的方法非常复杂冗长。所以我的问题是我试图加快多线程的处理速度。该应用程序用于在我的 2D 游戏引擎中进行照明,我在场景顶部绘制不同透明度级别的黑色矩形(目前导致延迟)。
对我来说,第一步是将具有相同亮度的相邻矩形批处理在一起,以减少一些渲染工作。这效果很好(也许可以做得更好,但现在不是重点),现在我还实现了一个粗略的线程系统,它将每批一起为屏幕的一个单独部分照明。
我的问题的关键:在分析上述特定批处理方法的时间时(针对不同数量的线程处理单独的、不相交的数据集),我注意到一些奇怪的峰值。以前,当使用一个线程时,该方法执行大约需要 12ms,奇数跳转到 15ms。我没想太多。然而,当使用 2 或 3 个线程进行处理时,我得到或多或少的 4~5 毫秒,跳跃到 10 毫秒,有时甚至高达 20 毫秒。
现在我意识到,如果不检查我的代码,任何人都无法说出原因可能是什么,所以我不希望这样。相反,我试图得出一些结论,并希望现在确认它们。如前所述,每个线程都在我的数据集的一部分上工作,彼此完全不相交(它们不重叠)。但是,数据数组的入口点是通过特定类的相同实例的相同方法。所以线程都通过相同的方法访问同一个数组(但它的不同部分 - 因此我也不使用任何锁)。这会导致意外减速吗?
或者线程以这种方式操作可能是正常行为(执行时间变化到标准的两倍以上)?另外,我在需要的时候创建所有线程他们,让他们运行到完成。
数据集的访问方式:
public short GetLightLevelAt(int x, int y)
{
if (inLightingBounds(x, y))
{
return lightData[x, y];
}
else
{
return GuessLightLevelAt(x,y); //This won't ever happen currently, guaranteed
}
}
【问题讨论】:
-
您的计时测量结果表明:1. 发生阻塞时线程之间发生了一些争用,和/或 2. 操作系统正在进行一些后台处理。
-
由于底层硬件特性,访问数组肯定有好方法和坏方法。 GC 是否有可能导致您的峰值?是否有正在创建/销毁的对象?
-
@RobertHarvey 我怀疑争用,但我的知识可能有点有限,无法确定为什么会出现这种情况。您能否详细说明争用是如何发生的?这或多或少是我期望的答案!
-
当您
lock某物,而其他线程试图访问它时,就会发生争用。第二个线程必须等待第一个线程释放它的锁。 -
@itsme86 嗯,这很可能是一个原因。我什至没有想到这一点。我的数据集最初非常小,我创建了一些数组来帮助我进行批处理。它们曾经很小,因为照明分辨率曾经很可怕(大矩形)。但现在我打算将矩形缩小到一个像素的大小。所以数据结构要大得多。我现在会调查的!谢谢!
标签: c# multithreading performance