关于多线程渲染

关于QOpenGLWidget的多线程渲染 关于QOpenGLWidget的多线程渲染 背景介绍 我们知道,QOpenGLWidget是Qt中继承自QWidget的一个类,对OpenGL的渲染环境进行了很好的封装。用户在使用时只用继承并重写几个关键的虚函数即可完成OpenGL资源的准备和每帧画面的绘制。 但是,也正是因为QOpenGLWidget是继承自QWidget的一个类,也决定了它的绘制函数是在UI线程调用的,也就是说,当我们重写了Q... 阅读详情

转自:http://www.cnblogs.com/ixnehc/archive/2008/09/04/1284708.html

困扰了一个多月的问题,今天终于有个阶段性的了结了,虽然不知道算不算真正的了结.


多核的cpu现在是大势所趋,渲染是一个很费时的活,所以应该考虑考虑能不能利用多核来提升这部分的性能.引擎一开始没有在多线程方面作任何的考虑,因为我从来就不喜欢多线程,这方面的思考能力不强,而且一开始写个单线程的engine已经够费事了,要加入多线程的设计对我来说实在是太难了.但是在积累了这么多时间的经验以后,我开始考虑加入多线程的支持,这玩意对架构的影响很大,所以加入设计还是宜早不宜迟.一开始先加入了多线程载入资源的模块,也顺便恢复一下早已荒废多年的多线程编程技能.接下来就该考虑将渲染部分放入一个单独的线程中去了.

首先,为什么呢?为什么要把渲染部分放到一个单独的线程中去呢?有什么好处呢?我的理解是这样的:显卡可以看成是一个外设,渲染的过程就是cpu不停的给gpu发各种命令,根据d3d的文档上说,d3d内部有一个command buffer,cpu在调用各种d3d的api时,其实是往这个command buffer里添加命令,这个command buffer是有一定大小的,当这个buffer满了以后,会有一个flush过程:这个buffer里的命令会被一齐扔给gpu去执行,然后这个buffer会被清空,以接受新的命令.按照d3d的文档上说,这个flush过程是很慢的,它必须要等待这个command buffer里的命令全部被gpu执行完,才会返回,不过我自己测了测,似乎不完全是这样,会有等待,但等待的时间好像并不是全部的执行完这些命令的时间,具体为什么,我也搞不清楚,也许写显卡驱动的人会更了解一些吧,d3d对我们这些写应用程序的人来说就是黑盒子.不过阻塞是一定会有的.所以我认为可以把gpu连同D3D看成一个类似硬盘的io设备.cpu通过调用d3d的api来给这个设备发命令,大多数情况下,这些api立即就返回了(这些命令被cache在d3d内部的一个command buffer里),但是偶尔的,当一个api调用试图在一个已经满了的command buffer里再加入命令时,就会触发一次d3d内部的flush过程,而这个时候,这个api调用就必须等待这个io设备了,也就是cpu这个时候是空闲的,计算能力在这里被浪费了.很多关于d3d的教材都提到不要调用太多的draw call,应该把多个draw call合并在同一个batch里,我以前以为,可能是因为d3d api的调用本身有开销,我现在的理解是,draw call太多,会导致太多的d3d api调用,太多的命令,而这样会导致d3d内部的command buffer频繁溢出,从而导致d3d内部频繁的flush,加剧了cpu等待gpu的情况. 如果d3d的内部运作模式真是我上面描述的那样的话,把渲染部分放到一个单独的线程中去就显得有必要了,因为可以把cpu在等待gpu的时间充分利用起来,或者至少不会让这些等待耽误到主线程的运行.

接下来,就要考虑怎么来做了.显然,这是一个典型的producer-consumer的结构,主线程(procucer)将要执行的渲染命令不停的加到一个队列里,再开一个渲染线程(consumer)不停的从这个个队列里读取命令,并执行.一开始我主要考虑要减少这些命令的个数,这样实现可以简单些,效率可以高些,所以打算把我自己实现的整个渲染系统放到一个单独的线程中去,把原来的接口全部转换为可以被队列化的一个个命令.干了一段时间后,发现实现难度还不小,接口数量还是太多了,所以又打算把接口提升到更高的层次中去,也就是把整个场景的渲染模块放到一个单独的线程中去,这个渲染模块主要包含了渲染对象的场景管理以及渲染分类.这样做的确减少了接口数量,所以虽然比较艰辛,我终于几乎还是把它给实现了,不过就在接近实现的时候,我又把整个问题重新考虑了一下,发现似乎又走了弯路.我的想法是这样:
*.对于目前大多数的游戏,每一帧的运算主要包括两部分:渲染和逻辑.
*.对于3D游戏,gpu完成渲染部分,cpu完成逻辑部分.
*.渲染部分是非常耗时的,一般来说比逻辑部分的消耗的时间要多
*.发展的趋势是cpu朝多核方向发展,逻辑部分可以被分到多个线程去做.
*.XBOX360已经有6个核了.
*.gpu也会发展,但是目前的即时渲染的水平离电影级的渲染水平仍然有很大的差距.
*.所以,相当长的时间内,渲染的耗时仍然会是瓶颈
*.而目前的D3D的架构只允许使用一个单独的线程去驱动gpu
*.所以不应该让这个单独的线程做额外的工作了,也就是渲染线程应该越单纯越好,
*.而最最单纯的就是在这个渲染线程里只做一件事情,就是给D3D发命令.

所以最后我采取了这样的方法,我把所用到的D3D接口函数全部重新写了一下,在这些函数里,我把原来对d3d的调用全部转化成一个个的命令,加到一个队列里,而由一个单独的渲染线程从这个队列里读取命令,再把它们传递给D3D.这样做还有一个附加的好处就是,它对整个引擎的架构的影响很小,所有的功能被局限在一个集中的模块里,并且可以很方便的enable/disable,很方便的在多线程/单线程渲染这两者之间切换,便于对比调试.而且如果这个模块写得完美,甚至可以开放给公众使用.

Threading the OGRE3D Render System(by Jeff Andrews) ,这篇文章也提到过这种方法,它提出了三种线程化的方案,主要也是按照渲染线程所处的层级来分的,和我上面说的比较类似,并且讨论了不少实现细节.不过它似乎认为在最高层次上进行线程化可以最大限度的发挥多核的威力,我想他可能是站在cpu计算瓶颈的角度上来看的吧.作者也为在最低层次上线程化的方案(重写D3D接口)作了实现(有源代码下载,我参考了一下),并做了测试,但效果似乎并不那么显著.不过他说it's doable.

实现这套接口对我来说并不是件容易的事,先是磨磨蹭蹭花了一周才写完,测了一下,结果很糟糕,在同事的双核电脑上比单线程版本要慢很多,以我贫乏的多核应用经验,一开始我以为是cpu的问题,后来在vista上测试的时候,发现了不错的结果,多线程版本比单线程版本几乎快了一倍(说实话,我第一次对vista有了好感),但是xp下就不行,进而怀疑操作系统的问题,下载了一个多核性能的bench mark,结果一切正常,问题看来还是在自己身上.最终还是找出了问题所在.目前的这个测试用例在双核的电脑上的有不小的性能提升,执行时间大概是单线程版本的60%左右,在单核的电脑上性能有微小的下降.还没有用更多的例子测过,所以不一定能说明问题,但至少说明是有前途的,是doable的.

实现过程中有一个地方值得注意,就是vertex buffer的Lock()/Unlock()的处理.上面说的这篇文章里也重点提到了这个问题,并提出了两种解决方法,Partially Buffered Locks和Fully Buffered Locks.我的方法有所不同,我将vb的lock分为三种情况:
1.static的vertex buffer,通常这种vb用来存储不会发生变化的vertex 数据,一般只在初始化的时候需要lock()/unlock(),对性能的影响不是很大,所以在lock时,会对command buffer进行一次flush,也就是说主线程等待渲染线程将当前command buffer里的所有命令全处理完后,才进行lock()/unlock()
2.dynamic的vertex buffer,no overwrite的lock(),所谓no overwrite的lock,就是lock vb后,使用者可以保证不去覆写那些已经被用到的vertex数据(这些vertex的数据可能正在被gpu用来绘制),在这种情况下,可以比较简单的处理,只要暂时冻结渲染线程的处理,然后进行lock就行了,然后在unlock后,再恢复渲染线程的处理.
3.dynamic的vertex buffer,discard的lock(),这种lock将会丢弃原来vb中的所有内容,这时候显然不能简单的对这个vb使用discard标志进行lock,因为使用这个vb进行绘制的命令可能还在command buffer里,等待渲染线程的处理.我一开始的解决方法是:先冻结住渲染线程的执行,然后添加一条release这个vb的命令到command buffer中去,然后再创建一个新的dynamic的vertex buffer,并对它进行lock,返回lock的数据指针,当unlock后,再恢复渲染线程的执行.后来做了些优化,因为在nVidia的卡上,创建一个vertex buffer似乎对性能有很大的影响,所以我改为使用一个vertex buffer的pool,vb不会被真正release掉,而是扔到这个pool里,当需要新的vb时,再从这个pool里分配.这样可以使性能开销降到最低.
在实际应用中,情况2应该是最常使用的,它的性能开销也是最小的.只需要要锁一下渲染线程.
对于texture/surface的lock()/unlock(),似乎没有很好的方法,必须flush一下command buffer.好在这种情况并不会太频繁的出现.而偶尔flush一下command buffer也不是那么的不可忍受.

顺便提一下多线程编程的一个注意点,A线程访问变量a,同时B线程访问变量b,如果a和b这两个变量在地址空间上离的很近的话,是会降低性能的,不能做到真正的同步访问,所谓false sharing.要避免这种情况,这两个变量要分配在不同的内存段上面,内存段的长度可能和硬件有关系吧,一般比如说128个字节,不放心的话,再远一点.

 

虚幻引擎之多线程渲染机制 虚幻引擎之多线程渲染机制 文章目录虚幻引擎之多线程渲染机制一、前言二、游戏线程与渲染线程的交互2.1 ENQUEUE_RENDER_COMMAND宏2.2 渲染线程2.3 数据交互2.3.1 数据更新2.3.2 创建渲染器2.3.3 触发渲染管线2.4 同步三、渲染线程与RHI线程3.1 RHI线程的创建3.2 RHI的任务参考文章 一、前言 在 虚幻引擎编程基础(二) 中,笔者简单地介绍了虚幻引擎中的多线程的类型,共分为三类: 标准多线程实现FRunnable; 使用线程池的AsyncTask; Tas 阅读详情

相关推荐

CEF渲染性能优化与多线程设计

性能优化和多线程设计是 CEF 应用开发中的核心组成部分。通过减少页面的重绘和回流,优化渲染流程,以及合理设计多线程架构,开发者可以显著提高应用的渲染性能和响应速度。此外,借助 GPU 加速和线程池等技术,开发者能够减轻 CPU 的负担,提升应用的流畅度和稳定性。在实际开发过程中,开发者应根据应用的具体需求和目标平台的特性,灵活运用各种优化技术,以实现最佳的性能表现。15年物联网开发、带过10-20人的团队,多次帮助公司从0到1完成项目开发,在TX等大厂都工作过。当下为退役状态,写此篇文章属个人爱好。

好看资源网的博客 1660

现在游戏引擎都必须多线程渲染么?

多线程渲染的确在现代游戏开发中变得越来越重要,尤其是在性能要求较高的场景中,但这并不意味着所有游戏引擎都必须支持多线程渲染。以下是关于多线程渲染的必要性、优劣势分析,以及为何一些引擎(如 Ogre 或 Cocos2d)可能并未采用多线程渲染的原因。现代引擎逐步向多线程渲染转变,这是硬件和图形 API 发展的趋势,但对于较轻量级的游戏和移动平台,单线程渲染仍然是一个高效且可靠的选择。多线程渲染是指在渲染管线中,多个线程协同工作来完成渲染任务,以更高效地利用多核 CPU 的计算能力。

小宝哥Code的专栏 2779

FPS 游戏中的多线程战斗艺术:把一场枪战拆成一支交响乐团

FPS游戏中的多线程和异步处理技术如同战场上分工明确的特种部队:多线程让CPU像多个士兵各司其职(渲染、逻辑、物理等),避免单线程"堵车";异步处理则像弹药补给不影响主战斗,提升效率。关键应用包括:分离渲染与逻辑线程、多线程物理计算、异步资源加载、异步网络通信和多线程AI计算。这些技术协同工作,确保高帧率运行,避免卡顿,为玩家带来流畅的战斗体验。通过任务分解与并行处理,现代FPS游戏实现了堪比真实战场的快速响应能力。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 2180

动态调整多线程渲染优化性能

CS 架构是指架构,这是一种网络架构模式,通常用于分布式系统。Client(客户端)客户端是向服务器请求服务的应用程序或设备。客户端通常负责用户界面和用户交互,向服务器发送请求并接收响应。Server(服务器)服务器是提供服务的应用程序或设备。它接收来自客户端的请求,处理这些请求,并返回结果。服务器通常负责数据存储、业务逻辑处理等。分离关注点:客户端和服务器可以独立开发和维护。可扩展性:可以根据需要增加更多的客户端或服务器。集中管理:服务器可以集中管理数据和业务逻辑。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 1990

NetApp 7-mode初始化详解(原AGGR重建)及注意事项

没想到有生之年还能再写个7-mode的文章,上次接触可能已将近十年,本次恰巧碰到这个机会,边学习边整理,整整一天时间,碰到了不少坑,作为记录。

RaySun的技术Blog 2751

【AI生成】 LoRa无中心自组网实现方案

LoRa技术是一种低功耗广域网通信技术,它采用了扩频频率调制技术,能够实现远距离的传输。LoRa在物联网中具有重要的应用价值,可以支持大规模的设备连接并且具有较低的成本。同时,LoRa具有高度的抗干扰能力和适应性,能够在复杂的环境中实现稳定的通信。通过使用无中心自组网实现方案,可以进一步提高LoRa网络的灵活性和可靠性,实现设备之间的智能互联。LoRa无中心自组网实现方案将为物联网应用提供更加便捷和高效的通信解决方案。LoRa无中心自组网实现方案一、无中心自组网概念及优势。

qq_31310977的博客 2088

C++游戏引擎多线程渲染优化实战(从卡顿到60FPS的蜕变)

解决游戏卡顿难题,实现C++游戏引擎多线程渲染优化。通过任务分帧、渲染线程分离与数据同步机制,提升帧率至稳定60FPS,适用于中大型2D/3D游戏开发。显著降低CPU负载,增强画面流畅性,值得收藏的性能优化实战指南。

CompiWander的博客 1012

kettle写doris操作

文件在目录:doris-master\extension\kettle\assemblies\plugin\target\doris-stream-loader-plugins-9.4.0.0-343.zip。官方提供了doris stream load插件,下载源码编译后放到kettle的插件目录即可使用。地址:https://github.com/apache/doris.git。注意:需要doris插件或者kettle转换生成模板的私聊博主。使用PDmaner同步业务库生成建表语句。

weixin_44449054的博客 3029

QOpenGLWidget的多线程渲染

关于QOpenGLWidget的多线程渲染_VE视频引擎的博客-优快云博客_qopenglwidget

sunxiaopengsun的专栏 3857

算法策略 | MACD跨周期短线交易策略开发(股指+商品双版)

量化策略开发,高质量社群,交易思路分享等相关内容

松鼠宽客的博客 2538

【保姆级教程/代码】使用PRIDE PPP-AR软件解算ZTD、反演GNSS PWV,并评估精度

在本算例中,我下载了BJFS站2024年的IGS ZTD产品,用于评估PRIDE PPP-AR软件解算出ZTD结果的精度。

weixin_43910227的博客 2367

《图解UE4渲染体系》Part 1 多线程渲染

上回书《Part 0 引擎基础》说到,我们粗略地知道UE4是以哪些类来管理一个游戏场景里的数据的,但这仅仅是我们开始探索UE4渲染体系的一小步。 本回主要介绍UE4渲染体系中比较宏观顶层的一部分——多线程渲染,具体的多线程中,又分为: 游戏线程(GameThread) 渲染线程(RenderThread) RHI线程(Render Hardware Interface Thread) 为什么是多线程? 用来描述“渲染”的最基础的理论就是像图上的那样,CPU调用图形API提供的DrawCall命令(也

ACStudio 4260

ubuntu linux虚拟机安装部署openclaw详细教程(安装、问题处理)

本文详细介绍了在Ubuntu系统下安装OpenClaw AI助手的完整流程及常见问题解决方案。主要内容包括:1) 通过GIT、Node.js等基础环境配置;2) 使用官方脚本或源码编译两种方式安装OpenClaw;3) 配置向导中的关键选项说明;4) 针对systemctl服务启动失败等常见错误的处理方法。文章特别强调了权限管理、网络依赖和访问配置等易错环节,提供了修改service文件等具体解决方案,帮助开发者顺利完成部署并实现Web UI访问。教程实操性强,适合本地和云服务器环境部署参考。

少说,多做 2031

OSG 高效渲染 之 多线程模型与渲染

这里以OSG多线程渲染为例,谈谈OSG渲染引擎多线程渲染模式,再说说哪里有点“过时”了需要改进。 先谈点题外话,曾经看到知乎上一篇关于游戏引擎的设计讨论的文章,有位“大大”提出游戏引擎的设计关键在于架构设计,这是灵魂,一味强调画质如何,shader , 特效算法写的如何好,渲染的怎么真实漂亮那是舍本逐末,这些都可以照着“Real-TimeRendering” 或 是相关的 paper 实现即可...

fatcat123的博客 5872

SXU-软件项目管理-朱少民-第九章 项目监控与控制 第十章 项目收尾 附相关习题

软件项目管理-朱少民-第九章 项目监控与控制 附相关习题

weixin_63597914的博客 1488

Pointnet++改进90:2025最新改进模块-EVA模块

本教程提出了一种改进PointNet++特征提取模块的方法,通过在PointNetSetAbstraction模块中加入NAMAttention注意力机制,显著提升了模型性能。具体改进包括:1)新建eva.py文件,实现了包含SDLSKA、CKS等关键组件的EVA模块;2)在pointnet2_utils.py中添加Conv和PointNetSetAbstractionAttention类,整合注意力机制;3)修改pointnet2_sem_seg.py模型结构。这种改进方法降低了实现难度,同时保持了33F

AIcurator的博客 361

多线程渲染

https://msdn.microsoft.com/zh-cn/communitydocs/game-development/directx-12-white-paper/ta15073006 这个链接失效了http://gad.qq.com/common/getfile?fileurl=server1/20150831/phpBn94r5.1441015741.pdf%7C%7...

anfu8346的博客 428

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

QOpenGLWidget多线程渲染

在 QOpenGLWidget 的多线程渲染中,如果渲染速度不够快或者图像质量不高,需要优化代码,比如调整线程的工作分配,或者改进渲染算法。有的负责切菜,有的负责炒菜,有的负责装盘。这就像在 OpenGL 渲染中,不同的线程可能负责不同的任务,比如计算、纹理加载、渲染等。这就像是 GPU 上的不同线程在执行它们的渲染任务,比如计算图形的坐标、应用纹理、设置光照效果等。:当顾客(应用程序)点菜(发起渲染任务)时,厨房(GPU)需要根据菜单来准备食物(渲染图像),这就像是告诉 GPU 需要渲染什么内容。

qq_44928767的博客 709

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Vulkan 多线程渲染

1. Overview of Vulkan 1.1 计算机图形软件 图形软件有两个大类:专用软件包(special-purpose packages)和通用编程软件包(general program- ming packages)。 专用软件包通常提供一种UI设计语言,让用户直接生成想要的图形,不用关心内部实现。这类软件例子是PS、CAD等等。 相反,通用编程软件包提供一个可使用C、C++或Java等高级语言编程的图形函数库。图形函数库中提供几何图元、矩阵变换等操作,提供了间接操作硬件的软件接口,所以这组图

Fery的博客 2376

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Vulkan_多线程渲染

用了这么长时间的vulkan渲染,我们本次主要来尝试使用vulkan相对于其他图形api的一个优势:多线程渲染。 本次我们主要来实现:在多个线程中平分渲染1024个模型并且在cpu中根据模型位置实现一个简单的视锥体剔除。 一、理论基础 文章开始之前,我们先来介绍两个vulkan常用功能:Fence及副命令缓冲区。 栅栏(fence):当主机需要等待设备完成某次提交中的大量工作时使用,通常需要操作系统的协助。是中等级量的同步语句。 副命令缓冲区:是可以由主命令缓冲区调用的命令缓冲区,副命令缓冲区可以从主命令

qq_35312463的博客 2355

Unreal基础多线程及渲染多线程

unreal engine(ue)支持多线程执行和渲染,优化了游戏和应用程序的性能。在多线程执行方面,ue允许并行处理多个任务,如物理计算、人工智能逻辑和网络通信,提高cpu使用率和响应速度。对于多线程渲染,ue采用延迟渲染技术,将渲染任务分配到多个核心上同时进行,有效减少画面撕裂和提升帧率,为玩家带来流畅的视觉体验。

llsansun的博客 2022

Vulkan下多线程渲染设计

之前项目一直大范围的运行在vulkan之上,但是比较可惜的是面对vulkan这种新一代的api,很多先进的特性并没有被实际运用,一个最关键的特性就是多线程渲染的能力,最近把vulkan的多线程渲染实现到了项目中,取得了不错的性能提升,也刚好很久没有写文章,特此记录下这里面的一些实现,思考和棘手的问题(本文基于UE4实现)。

leon 6610

Qt使用OpenGL进行多线程离屏渲染

基于Qt Widgets的Qt程序,控件的刷新默认情况下都是在UI线程中依次进行的,换言之,各个控件的QWidget::paintEvent方法会在UI线程中串行地被调用。如果某个控件的paintEvent非常耗时(等待数据时间+CPU处理时间+GPU渲染时间),会导致刷新帧率下降,界面的响应速度变慢。 假如这个paintEvent耗时的控件没有使用OpenGL渲染,完全使用CPU渲染。这种情况处...

imred的专栏 1万+
上一篇: 矩阵的本质-运动的描述【好】
下一篇: D3D渲染流程简介【好】
HNFXS985
博客等级 码龄14年 219粉丝 150原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值