@@ -1746,7 +1746,13 @@ export let exec: execType<worldState> = (worldState, { getStatesFunc }) => {
17461746## 遵循的设计原则在UML中的体现?
17471747
17481748
1749- TODO finish
1749+ 多线程模式主要遵循下面的设计原则:
1750+ - 单一职责原则
1751+ 每个线程只做自己的事情,只更新自己的数据,这样就减少了各个线程之间发生冲突的可能性
1752+ - 最少知识原则
1753+ 其它线程之间互相不知道,它们只知道主线程;
1754+ 线程之间只知道发送过来的与该线程相关的数据
1755+
17501756
17511757
17521758# 应用
@@ -1758,15 +1764,16 @@ TODO finish
17581764
17591765## 缺点
17601766
1761- - 如果需要同时支持单线程和多线程运行环境的话,则需要同时维护单线程和多线程的这两个管道的代码
1762- 好消息是因为使用了管道模式,所以进行了充分的解耦,使得这两套代码互不影响
1767+ - 如果需要同时支持单线程和多线程运行环境的话,需要同时维护单线程和多线程的这两个管道的代码,它们有很多逻辑是重复的
1768+ 好消息是因为使用了管道模式,所以进行了充分的解耦,两套代码互不影响
1769+ 另外,可以把重复的逻辑提出来放到公共的utils模块中,然后让这两个管道的Job调用它们,从而可消除重复代码
17631770
1764- - 需要考虑考虑线程之间的同步
1771+ - 需要考虑线程之间的同步
17651772好消息是不需要锁,而是通过共享和备份来实现同步,这样更易于维护且性能更高
1766- 要实现这种同步的话,可从下面几个方面来考虑 :
1767- 共享的数据尽量使用不可变数据,因为修改它不需要同步 ;
1768- 其它线程尽量只读主线程的数据 ,这样就不需要同步;
1769- 设计同步时,从数据的角度出发 ,识别出主线程哪些数据会被其它线程写;然后备份这些数据,并让其它线程写该备份数据;最后在同步时从备份中更新主线程数据
1773+ 要使用这种同步方案的话,需要注意下面几个方面 :
1774+ 共享的数据尽量使用不可变数据,这样修改它们后不需要同步 ;
1775+ 其它线程尽量只读而不写主线程的数据 ,这样就不需要同步;
1776+ 在设计时,可以从数据的角度出发 ,识别出主线程哪些数据会被其它线程写;然后备份这些数据,并让其它线程改为写到该备份数据中 ;最后在主线程同步时,从备份中更新主线程数据
17701777
17711778
17721779## 使用场景
@@ -1781,9 +1788,8 @@ TODO finish
17811788
17821789可以将渲染的逻辑从主线程移到一个渲染线程来并行地执行
17831790
1784- - 开多个线程来并行地执行一些逻辑,如加载超大模型、进行复杂计算等逻辑
1785- 可以开一个线程去加载超大模型,开另一个线程去进行复杂计算;
1786- 每帧的最后在主线程进行同步
1791+ - 需要处理加载超大模型、进行复杂计算等并行逻辑
1792+ 对于有这些并行逻辑的系统,可以开多个线程来并行地执行一些逻辑,具体如可以开一个线程去加载超大模型,开另一个线程去进行复杂计算;每帧的最后在主线程进行同步
17871793
17881794
17891795
@@ -1792,12 +1798,12 @@ TODO finish
17921798
17931799- 如果其它线程需要写主线程的数据,则需要同步
17941800
1795- - 使用SharedArrayBuffer时,需要启用跨域隔离
1801+ - 使用SharedArrayBuffer时,需要启用浏览器的跨域隔离
17961802
17971803
17981804# 扩展
17991805
1800- - 如果材质有纹理 ,则需要将纹理图片从主线程传到渲染线程,这可以通过浏览器的transferFromImageBitmap API来传送该图片
1806+ - 如果材质包括了纹理 ,则需要将纹理图片从主线程传到渲染线程,这可以通过浏览器的transferFromImageBitmap API来传送该图片
18011807
18021808- 如果是现代图形API,如DX12/Vulkan/Metal/WebGPU,则支持开多个而不是一个渲染线程来渲染
18031809
@@ -1854,7 +1860,7 @@ TODO finish
18541860# 更多资料推荐
18551861
18561862
1857- 因为游戏的场景一般都比较大,所以游戏引擎一般都支持多线程
1863+ 因为游戏的场景一般都比较大,所以游戏引擎(如Unity、Unreal)一般都支持多线程
18581864
18591865
18601866顽皮狗在GDC上提出了Fiber架构,使用了管道模式,支持多线程,具体可在网上搜索“Parallelizing the Naughty Dog Engine using Fibers”
0 commit comments