Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C OpenGL多线程处理比使用单个线程慢_C_Multithreading_Opengl - Fatal编程技术网

C OpenGL多线程处理比使用单个线程慢

C OpenGL多线程处理比使用单个线程慢,c,multithreading,opengl,C,Multithreading,Opengl,我使用的是Windows7和VC++2010,这是一个32位的应用程序 我试图让我的渲染器工作多线程,但事实证明,我使它慢于不使用多线程 我希望它有一个主线程向列表中添加渲染命令,以及一个执行这些命令渲染的工作线程 这一切都发生了,它吸引到屏幕上的罚款,但我得到较少的fps时,这样做 我使用Fraps中的基准工具来获取以下数据: 时间是基准测试的时间,在本例中为30秒 最小值、最大值、平均值均为FPS值 使用多线程: Frames, Time (ms), Min, Max, Avg

我使用的是Windows7和VC++2010,这是一个32位的应用程序

我试图让我的渲染器工作多线程,但事实证明,我使它慢于不使用多线程

我希望它有一个主线程向列表中添加渲染命令,以及一个执行这些命令渲染的工作线程

这一切都发生了,它吸引到屏幕上的罚款,但我得到较少的fps时,这样做

我使用Fraps中的基准工具来获取以下数据:

时间是基准测试的时间,在本例中为30秒

最小值、最大值、平均值均为FPS值

使用多线程:

    Frames, Time (ms), Min, Max, Avg
     28100,     30000, 861,1025, 936.667
Frames, Time (ms), Min, Max, Avg
 21483,     30000, 565, 755, 716.100
没有多线程:

    Frames, Time (ms), Min, Max, Avg
     28100,     30000, 861,1025, 936.667
Frames, Time (ms), Min, Max, Avg
 21483,     30000, 565, 755, 716.100
以下是一些伪代码(以及相关的事件函数调用):


你为什么期望这会更快

只有一个线程在做任何事情,您在一个线程中创建命令,并向另一个线程发送信号,然后等待它完成,这将花费与在第一个线程中执行相同的时间,只会增加开销


要利用多线程,您需要确保两个线程同时执行某些操作

我不是opengl专家,但总的来说,重要的是要认识到线程实际上并不是用来加速事情的,它们是为了保证某些子系统以牺牲总体速度为代价做出响应。也就是说,可以保留一个gui线程和一个网络线程,以确保gui和网络具有响应性。这实际上是以主线程的性能代价来完成的。CPU将把1/3的时间分配给主线程,1/3的时间分配给网络线程,1/3的时间分配给gui线程,即使没有gui事件要处理,也没有任何东西进出网络。因此,无论主线程在做什么,其CPU时间只占非多线程情况下的1/3。这样做的好处是,如果大量数据开始通过网络到达,那么总会有CPU时间来处理它(如果没有,这可能会很糟糕,因为可以填充网络缓冲区,然后开始删除或覆盖额外的数据)。可能的例外是,如果多个线程在不同的内核上运行。但是,即使如此,也要小心,内核可以共享相同的缓存,因此如果两个内核使彼此的缓存失效,性能可能会显著下降,而不是提高。如果内核共享一些资源来将数据移动到GPU或从GPU移动数据,或者拥有一些其他共享的限制资源,这同样可能导致性能损失,而不是收益


简言之,单CPU系统上的线程始终与子系统的响应性有关,而不是性能。当不同的线程在多个内核上运行时,可能会有性能提升(默认情况下windows通常不会这样做,但可以强制执行)。但是,如果这些核心共享一些可能会损害而不是帮助性能的资源,例如共享缓存空间或您上下文中与GPU相关的共享资源,则执行此操作可能会出现潜在问题。

作为一项健全性检查:如果使用参数bManualReset=false调用CreateEvent(),会发生什么情况,然后跳过对ResetEvent()函数的所有调用?如果为false,WaitFor函数将自动清除事件。使用-936fps,W/O-716。真的有什么问题吗?@BartekBanachewicz这只是一个opengl调用的测试集,当我把所有的东西都设置好后,会有更多的opengl调用,我想这比Lundin更重要,当我这样做的时候,我得到了相同的结果,好像你的线程只是在轮换。为了获得合适的生产者/消费者,请等待队列中有足够的开放空间,不适用于队列再次完全为空。因此,与其让主线程等待渲染线程完成,我应该丢弃从主线程发送的命令,并允许它执行其他操作,直到渲染线程完成?建立渲染列表并像您所做的那样将其发送到渲染线程,但是,在渲染线程处理第一个渲染缓冲区时,创建一个新的渲染缓冲区并开始填充,以便它们可以重叠。显然,这使同步变得更加复杂……我有几个问题:拥有2个命令队列是理想的,还是应该拥有更多?如何处理比渲染线程快得多的主线程?如果其中一个命令队列已满且渲染线程尚未找到,它可以跳过渲染吗?这里很难回答这个问题,因为这都是主要的设计内容。我会在生成新命令列表后等待渲染线程,这样您就不会领先,但仍然可以重叠一点。请注意,在某种程度上,呈现API已经在内部完成了这项工作,因此您可能无法从中获得预期的收益。另外,在使用来自两个线程的opengl命令时需要小心,我不确定什么是合法的,因为我知道direct3d有某些限制。@MichaelIV:不,你不能。您可以设置两个上下文(共享或不共享,无所谓)并呈现两个不同的、不相关的内容,但这没有帮助。如果使用共享上下文,您可以进一步使用一个上下文来更新纹理和缓冲区,但与上面的解决方案相比,您不会获得额外的性能,因为GL将尽其所能进行同步(事实上,在某些驱动程序上,这会导致性能显著降低,并且在某些情况下,您可能会得到意外的结果)。不能“并行渲染”。