Skip to content

Commit 55786f5

Browse files
committed
feat(多线程模式): finish update
1 parent c319311 commit 55786f5

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

packages/多线程模式/article.md

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)