偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

我們一起聊聊如何利用并行計算挖掘性能極限

開發(fā) 前端
在數(shù)據(jù)流交互架構(gòu)中,不同并行執(zhí)行單元的處理消息速率通常不一致,因此需要借助消息隊列緩存來協(xié)調(diào)。在 Java 中,各種并發(fā)的 BlockingQueue 就是這種消息隊列的一種實現(xiàn)方式,即典型的生產(chǎn)者消費(fèi)者模型的處理方法。

在當(dāng)前的計算機(jī)領(lǐng)域中,CPU 單核性能的增長已逐漸停滯,而業(yè)務(wù)問題的復(fù)雜度卻不斷上升。為了更好地解決這一沖突,在 CPU 中增加核數(shù)成為了常見的應(yīng)對方案。在這種情況下,并行設(shè)計的重要性日益凸顯,它能夠充分發(fā)揮硬件多核的運(yùn)行性能。

然而,要通過并行設(shè)計將計算負(fù)載均衡到每個 CPU 核上,并將軟件性能提升至最大化,面臨著諸多挑戰(zhàn)。例如,并行拆分不合理可能導(dǎo)致產(chǎn)品性能不可控甚至惡化,程序員的串行編程慣性思維使得并發(fā)同步互斥實現(xiàn)中的故障難以定位,進(jìn)而導(dǎo)致產(chǎn)品在較長時間內(nèi)處于不可用狀態(tài)。

為了應(yīng)對這些挑戰(zhàn),我們首先需要了解并行計算模型。在面對具體的業(yè)務(wù)問題時,我們需要將其拆分成可并行的邏輯單元,并實現(xiàn)同步交互。并行計算模型可以幫助我們建立對并發(fā)系統(tǒng)的抽象模型和基本概念的認(rèn)識。

具體來說,并行計算模型可以抽象為兩個層次:一是由結(jié)構(gòu)數(shù)據(jù)和相應(yīng)的計算邏輯組成并發(fā)執(zhí)行單元,通過組合實現(xiàn)更復(fù)雜的業(yè)務(wù);二是基于各種手段(如內(nèi)存、互斥量、消息隊列、數(shù)據(jù)庫等)對并發(fā)執(zhí)行單元計算的結(jié)果進(jìn)行交互同步,保證業(yè)務(wù)計算結(jié)果的確定性。

需要注意的是,并行執(zhí)行單元的粒度可大可小,不僅僅局限于線程。在設(shè)計并發(fā)架構(gòu)時,我們應(yīng)根據(jù)處理的特定領(lǐng)域問題,選擇合適的并行執(zhí)行單元粒度,并選擇或定制實現(xiàn)相應(yīng)的并發(fā)調(diào)度框架。

接下來,我們介紹六種針對不同業(yè)務(wù)問題的典型并行設(shè)計架構(gòu)模式。

第一種是任務(wù)線性分解架構(gòu),它是按照計算邏輯維度進(jìn)行確定性拆分的并行架構(gòu)設(shè)計模式。當(dāng)單核處理性能存在瓶頸時,通過依賴分析,發(fā)現(xiàn)計算邏輯相對獨立,便可按照計算邏輯拆分成獨立的并行執(zhí)行單元,從而提升性能。這種架構(gòu)模式適用于業(yè)務(wù)邏輯確定性的場景,但需要注意消除或隔離數(shù)據(jù)依賴、確定執(zhí)行單元工作量以及任務(wù)線性拆分?jǐn)U展性差等問題。

圖片圖片

當(dāng)我們觀察圖中的左側(cè)時,可以看到計算邏輯 A、B 和 C 在同一個數(shù)據(jù)塊上進(jìn)行操作。通過依賴性分析,我們可以發(fā)現(xiàn) A、B 和 C 這三個計算邏輯是相對獨立的。因此,當(dāng)單核處理性能達(dá)到瓶頸時,可以通過計算邏輯維度進(jìn)行并行拆分來提升性能。

圖的右側(cè)展示了通過這種拆分形成的三個獨立并行執(zhí)行單元。這種方式可以映射到兩個硬件線程上,從而減少處理時延。

補(bǔ)充說明:對于 Java 工程師來說,需要顯式地將任務(wù)映射到硬件線程的情況可能比較少;但對于嵌入式工程師來說,任務(wù)與硬件線程的映射綁定是并行設(shè)計中的一個關(guān)鍵環(huán)節(jié)。

實際上,在許多業(yè)務(wù)領(lǐng)域中,都存在需要根據(jù)同一個事件或數(shù)據(jù)并行觸發(fā)多個任務(wù)的場景。例如,在電商購物場景下,一筆交易成功后,系統(tǒng)會同時觸發(fā)多項任務(wù),包括生成郵件通知責(zé)任人、進(jìn)行多維度數(shù)據(jù)統(tǒng)計及更新等。

當(dāng)這些觸發(fā)的業(yè)務(wù)計算邏輯相互獨立時,可以創(chuàng)建多個并行執(zhí)行單元,分別處理拆分后的不同子任務(wù),并根據(jù)各執(zhí)行單元的工作量大小,將其與具體的硬件線程建立映射和綁定關(guān)系。

這種并行設(shè)計架構(gòu)相對簡單,適用的業(yè)務(wù)場景也比較多。例如,在觀察者模式中處理類似問題、在消息隊列中解決一對多通信的業(yè)務(wù)問題等,都隱含著任務(wù)線性并發(fā)的可能性。

總的來說,任務(wù)線性分解架構(gòu)適用于業(yè)務(wù)邏輯確定性的場景。在實際應(yīng)用中需要注意以下幾點:

  1. 在并行執(zhí)行單元間,通過一些手段消除或隔離數(shù)據(jù)依賴,例如使用 ThreadLocal 變量,通過數(shù)據(jù)冗余來消除依賴。
  2. 執(zhí)行單元的工作量較為確定,便于與硬件線程建立綁定和映射關(guān)系。
  3. 進(jìn)行并行拆分時,需要先了解全局的業(yè)務(wù)功能。任務(wù)線性拆分的擴(kuò)展性相對較差。

通過這些方法,任務(wù)線性分解架構(gòu)能夠在特定場景下有效提升性能。

第二種是任務(wù)分治架構(gòu),它是按照計算邏輯進(jìn)行動態(tài)拆分的并行架構(gòu)設(shè)計模式。在許多業(yè)務(wù)場景中,計算邏輯并非全局確定,需要根據(jù)場景判斷是否拆分成更小的子問題進(jìn)行求解。在這種情況下,需要動態(tài)創(chuàng)建任務(wù),并借助任務(wù)隊列來管理執(zhí)行任務(wù)。這種架構(gòu)模式的使用場景相對較少,但在一些實時性要求高、性能要求苛刻的場景下,如股票交易等,任務(wù)隊列以及硬件資源綁定關(guān)系通常需要單獨設(shè)計實現(xiàn)。

圖片圖片

通過圖中的左側(cè),我們可以發(fā)現(xiàn),在許多業(yè)務(wù)場景中,計算邏輯并不是全局確定的。在計算過程中,有些業(yè)務(wù)需要根據(jù)具體場景來判斷是否將其拆分成更小的子問題進(jìn)行求解。例如,A 計算過程中會拆分出 2 個 B 子問題,而這 2 個子問題在計算過程中又需要進(jìn)一步拆分為 3 個 C 子問題來求解。

針對這種動態(tài)變化的場景進(jìn)行并行設(shè)計時,不能在系統(tǒng)運(yùn)行前完成任務(wù)的拆分,而是需要在運(yùn)行時動態(tài)創(chuàng)建任務(wù),并借助任務(wù)隊列來管理和執(zhí)行這些任務(wù)。執(zhí)行線程可以從隊列中拉取任務(wù)。在并行執(zhí)行單元間,數(shù)據(jù)依賴可以通過一些手段進(jìn)行消除或隔離,比如利用 ThreadLocal 變量或通過數(shù)據(jù)冗余來處理。這樣,執(zhí)行單元的工作量相對確定,便于與硬件線程建立綁定和映射關(guān)系。

通常情況下,在進(jìn)行并行拆分時,需要先了解全局的業(yè)務(wù)功能,盡管任務(wù)線性拆分的擴(kuò)展性相對較差。這種并行設(shè)計架構(gòu)模式的使用場景相對少一些。

例如,我之前基于 Akka 框架設(shè)計開發(fā)了一款智能對話引擎。在這個對話引擎系統(tǒng)中,用戶對話的語義信息是有限的。當(dāng)收到某個用戶對話數(shù)據(jù)時,在特定上下文中,其語義可能只是全局語義中的一個較小子集。因此,我需要在這個子集中選擇語義匹配率最高的一個進(jìn)行回復(fù)。

每個語義匹配率的計算邏輯與對話數(shù)據(jù)是獨立的。為了實現(xiàn)用戶對話消息的快速回復(fù),我需要在特定上下文下,動態(tài)創(chuàng)建多個并行執(zhí)行單元,分別計算語義匹配度,然后匯總選擇匹配率最高的一個。這種實現(xiàn)框架基于任務(wù)分治架構(gòu)進(jìn)行設(shè)計。

實際上,在 Java 的 java.util.concurrent.Executors 以及 Akka 等框架中,已經(jīng)內(nèi)置了并發(fā)任務(wù)隊列,并支持與 CPU 等硬件線程的映射,從而滿足大部分場景下的業(yè)務(wù)需求。然而,在一些實時性要求較高、性能要求非??量痰膱鼍跋拢热绻善苯灰?,任務(wù)隊列以及硬件資源的綁定關(guān)系通常需要單獨設(shè)計實現(xiàn)。

1.數(shù)據(jù)幾何分解架構(gòu)

圖片

數(shù)據(jù)幾何分解和任務(wù)線性分解架構(gòu)風(fēng)格相似,但幾何分解架構(gòu)的主要特點是在不同的數(shù)據(jù)上執(zhí)行相同的計算邏輯。正如圖中右側(cè)所示,拆分成不同的并行計算單元后,計算邏輯是相同的(同色表示),但數(shù)據(jù)是不同的(不同顏色表示)。

在互聯(lián)網(wǎng)微服務(wù)場景中,業(yè)務(wù)關(guān)鍵數(shù)據(jù)通常記錄在數(shù)據(jù)庫表中。當(dāng)數(shù)據(jù)規(guī)模較大時,需要對數(shù)據(jù)庫表進(jìn)行分表策略保存,這就是一種典型的數(shù)據(jù)幾何分解方式。針對這種場景,當(dāng)接收到業(yè)務(wù)數(shù)據(jù)庫表查詢分析請求時,需要基于相同的計算邏輯和不同的數(shù)據(jù)庫分表組合,創(chuàng)建多個執(zhí)行單元并行計算以提升性能。

在業(yè)務(wù)發(fā)展過程中,待處理數(shù)據(jù)規(guī)模增加是一個非常重要的變化方向,通過彈性計算資源提升業(yè)務(wù)處理能力是核心關(guān)注點之一。數(shù)據(jù)幾何分解架構(gòu)是一種解決此類問題的典型方法,具有很多優(yōu)點,應(yīng)用非常廣泛。

最后,讓我們看看數(shù)據(jù)幾何分解架構(gòu)的隱式約束條件:

  • 擴(kuò)展性強(qiáng):采用數(shù)據(jù)幾何分解架構(gòu),其可支持的擴(kuò)展性會比較強(qiáng)。
  • 適用于 SPMD 架構(gòu):這種性能架構(gòu)模式比較適合于 SPMD(Single Program Multi Data)架構(gòu)。SPMD 架構(gòu)使用一套相同的代碼實體并行運(yùn)行在多個硬件線程上,這樣用戶只需要管理一套代碼實體即可,成本比較低。
  • 獨立更新:在數(shù)據(jù)幾何分解架構(gòu)中,不同并行計算單元的更新數(shù)據(jù)是獨立的。

2.遞歸數(shù)據(jù)結(jié)構(gòu)

圖片圖片

從圖中可以看到,業(yè)務(wù)處理的數(shù)據(jù)是樹狀或圖狀組織的,這表明線性幾何拆分?jǐn)?shù)據(jù)會比較困難。

因此,在實際應(yīng)用中,需要在遍歷過程中動態(tài)創(chuàng)建任務(wù),然后逐步合并每個中間計算單元的運(yùn)算結(jié)果,最終計算得到結(jié)果,如圖中右側(cè)所示。

MongoDB 是目前應(yīng)用非常廣泛的開源文檔數(shù)據(jù)庫,它支持將靈活的 JSON 格式業(yè)務(wù)數(shù)據(jù)保存到數(shù)據(jù)庫中。在對業(yè)務(wù)記錄 JSON 格式內(nèi)的多個字段進(jìn)行數(shù)據(jù)分析時,代碼需要遞歸遍歷 JSON 中所有嵌套字段并進(jìn)行分析計算。為了最大化并發(fā)執(zhí)行,減少處理時延,可以采用遞歸數(shù)據(jù)架構(gòu)模式,在遞歸遍歷字段過程中動態(tài)創(chuàng)建相應(yīng)字段分析的并行執(zhí)行單元。

這種架構(gòu)的應(yīng)用場景也相對較少,主要用于非規(guī)則結(jié)構(gòu)數(shù)據(jù)的計算分析,比如樹狀結(jié)構(gòu)、有向圖等數(shù)據(jù)結(jié)構(gòu)。

3.數(shù)據(jù)流交互架構(gòu)

圖片圖片

從上圖中我們可以發(fā)現(xiàn),這種業(yè)務(wù)場景的典型特征是計算單元的確定性較強(qiáng),可以靜態(tài)規(guī)劃與硬件線程的映射關(guān)系。設(shè)計的核心是如何高效實現(xiàn)并發(fā)計算單元間的信息交互。

具體如何實現(xiàn)呢?讓我舉個例子。

在大數(shù)據(jù)領(lǐng)域中,ETL(Extract-Transform-Load)是一個非常典型的場景,它描述了將數(shù)據(jù)從來源端經(jīng)過抽?。╡xtract)、轉(zhuǎn)換(transform)和加載(load)至目的端的過程。在這種架構(gòu)模式下,計算任務(wù)單元需要動態(tài)創(chuàng)建,且工作量不確定。

一般來說,遞歸數(shù)據(jù)架構(gòu)對應(yīng)的算法是遞歸算法。在這種架構(gòu)中,一個計算單元的輸出正好是另一個計算單元的輸入,消息交互是單向確定性的。同時,業(yè)務(wù)場景中還會源源不斷接收到新的輸入,需要使用相似的計算策略進(jìn)行處理。

業(yè)務(wù)數(shù)據(jù)處理需求通常由多個 ETL 階段組合完成,因此在這種場景下,使用數(shù)據(jù)流交互架構(gòu)會比較合適。此外,在嵌入式領(lǐng)域,網(wǎng)絡(luò)協(xié)議棧的報文處理、不同協(xié)議棧解析特定頭部字節(jié)、完成業(yè)務(wù)處理后透傳給下一層,也是使用數(shù)據(jù)流交互架構(gòu)的典型場景。

在數(shù)據(jù)流交互架構(gòu)中,不同并行執(zhí)行單元的處理消息速率通常不一致,因此需要借助消息隊列緩存來協(xié)調(diào)。在 Java 中,各種并發(fā)的 BlockingQueue 就是這種消息隊列的一種實現(xiàn)方式,即典型的生產(chǎn)者消費(fèi)者模型的處理方法。

通過這些手段,可以高效地實現(xiàn)并發(fā)計算單元間的信息交互,滿足動態(tài)創(chuàng)建任務(wù)和處理不確定工作量的需求。

4.異步交付架構(gòu)

圖片圖片

從圖上我們可以發(fā)現(xiàn),該業(yè)務(wù)場景的典型特點如下:

這種系統(tǒng)的計算邏輯可能需要進(jìn)行全局拆分,也可能無法拆分,需要根據(jù)實際情況進(jìn)行處理。

讓我給你舉個例子。在微服務(wù)架構(gòu)中,微服務(wù)在完成一個 REST 請求業(yè)務(wù)功能的過程中,可能需要進(jìn)行多次數(shù)據(jù)庫操作,還可能需要多次調(diào)用其他微服務(wù)提供的 REST 接口。為了充分發(fā)揮性能,當(dāng)我們將業(yè)務(wù)邏輯拆分為多個并行執(zhí)行單元后,并行執(zhí)行單元間的運(yùn)行開銷差異較大時,可以使用異步交互來實現(xiàn)業(yè)務(wù)功能。

請注意,要想最大化地發(fā)揮這種架構(gòu)的性能,還需要做到以下一點:并行執(zhí)行單元能夠動態(tài)靈活地映射到特定的硬件 CPU 核上。比如,Node.js 后端業(yè)務(wù)中的 async 機(jī)制和 Java 語言中的 Future 并發(fā)機(jī)制,都是支持異步交互架構(gòu)的較好語言機(jī)制。

通過這些方法,可以在微服務(wù)架構(gòu)中實現(xiàn)高效的異步交互,提高系統(tǒng)性能。

責(zé)任編輯:武曉燕 來源: 二進(jìn)制跳動
相關(guān)推薦

2024-02-26 00:00:00

Go性能工具

2021-11-04 06:58:31

CSS性能設(shè)備

2025-03-13 05:00:00

2024-07-11 08:26:00

2025-06-11 02:10:00

2024-02-02 09:21:57

API性能策略

2023-12-29 08:29:15

QPS系統(tǒng)應(yīng)用

2023-08-10 08:28:46

網(wǎng)絡(luò)編程通信

2023-08-04 08:20:56

DockerfileDocker工具

2023-06-30 08:18:51

敏捷開發(fā)模式

2023-09-10 21:42:31

2022-05-24 08:21:16

數(shù)據(jù)安全API

2024-09-30 09:33:31

2024-11-27 16:07:45

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環(huán)GolangGo

2024-09-09 00:00:00

編寫技術(shù)文檔

2023-04-03 00:09:13

2024-12-10 00:00:25

2021-12-10 07:45:48

字節(jié)音頻視頻
點贊
收藏

51CTO技術(shù)棧公眾號