自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

告別性能焦慮!C++17 并行算法從入門(mén)到精通

開(kāi)發(fā) 后端
隨著硬件性能的提升和C++標(biāo)準(zhǔn)的發(fā)展,并行算法必將在現(xiàn)代C++編程中發(fā)揮越來(lái)越重要的作用。掌握這項(xiàng)"神器",讓我們的代碼插上騰飛的翅膀! ?

"救命?。。?!" 小王抓著頭發(fā)盯著屏幕,都快哭出來(lái)了,"這破數(shù)據(jù)怎么處理了一整天還在跑?我的周末要泡湯了!"

老張悠哉悠哉地端著他那標(biāo)志性的"全宇宙最棒程序員"馬克杯晃了過(guò)來(lái),香濃的咖啡香氣飄得整個(gè)辦公室都是。"喲,遇到困難了?讓我瞧瞧..." 他推了推那副程序員標(biāo)配的黑框眼鏡,"哦~這不就是那個(gè)傳說(shuō)中的千萬(wàn)級(jí)用戶(hù)日志分析任務(wù)嘛!"

"可不是嘛!" 小王指著屏幕上密密麻麻的代碼欲哭無(wú)淚,"我用了std::accumulate 來(lái)做統(tǒng)計(jì),結(jié)果這程序跑得比蝸牛還慢,我都懷疑人生了!"

老張嘴角微微上揚(yáng),露出了一個(gè)"前輩高手"的神秘微笑:"年輕人,讓我來(lái)告訴你一個(gè)改變你程序人生的秘密神器 - C++17的并行算法!它就像是給你的程序裝上了火箭推進(jìn)器,讓數(shù)據(jù)處理飛起來(lái)!"

小王的眼睛一下子亮了起來(lái),整個(gè)人都從椅子上彈了起來(lái):"真的嗎?快教教我!"

初識(shí)并行算法

老張推了推眼鏡,露出高深莫測(cè)的微笑:"來(lái)來(lái)來(lái),讓我給你介紹一個(gè)編程界的超級(jí)英雄 - C++17的并行算法!"

"并行算法?聽(tīng)起來(lái)好像很厲害的樣子!" 小王的眼睛里閃爍著求知的光芒。

"其實(shí)啊,這就像是給你的程序配備了一支超級(jí)戰(zhàn)隊(duì)!" 老張眨眨眼睛,"我先給你解釋一下std::accumulate - 它就像是一個(gè)計(jì)數(shù)器,可以把一串?dāng)?shù)字都加起來(lái)。比如你要統(tǒng)計(jì)所有用戶(hù)的消費(fèi)總額,或者計(jì)算一組數(shù)據(jù)的總和,都可以用它。但它只能一個(gè)數(shù)一個(gè)數(shù)地慢慢加,就像是一個(gè)人在那里掰著手指頭數(shù)數(shù)。"

"來(lái)看看這段魔法代碼:"

// 以前只能一個(gè)人慢慢數(shù)磚頭 ??
// accumulate 會(huì)從頭到尾遍歷數(shù)據(jù),把每個(gè)數(shù)都加到初始值(這里是0)上
auto sum = std::accumulate(data.begin(), data.end(), 0);

// 現(xiàn)在可以叫上所有小伙伴一起數(shù)!??
#include <execution>
auto sum = std::reduce(std::execution::par, data.begin(), data.end(), 0);

"就...就這么簡(jiǎn)單?感覺(jué)像在變魔術(shù)!" 小王目瞪口呆。

"沒(méi)錯(cuò)!" 老張得意地晃了晃他的咖啡杯,"這就是現(xiàn)代 C++ 的魅力所在!只要加上std::execution::par 這個(gè)小魔法師 ,你的程序就能召喚出多個(gè) CPU 核心一起并肩作戰(zhàn)了!就像是給你的代碼裝上了渦輪增壓器,嗖的一下就飛起來(lái)了!"

程序重新編譯運(yùn)行,這次的速度簡(jiǎn)直像是坐上了火箭,不到半小時(shí)就完成了原來(lái)需要一整天的工作。

"哇塞!這也太神奇了吧!" 小王激動(dòng)地在椅子上轉(zhuǎn)來(lái)轉(zhuǎn)去,"感覺(jué)我的程序突然開(kāi)掛了!"

老張笑著喝了口咖啡:"記住啊,這個(gè)魔法雖然強(qiáng)大,但也要看場(chǎng)合使用。數(shù)據(jù)太少的時(shí)候,反而會(huì)因?yàn)檎賳?小伙伴'耽誤時(shí)間。就像叫一群人來(lái)搬一塊磚,光是組織大家就費(fèi)勁了!" 

"這個(gè)道理我懂!" 小王若有所思地點(diǎn)點(diǎn)頭,"就像打游戲,小怪用普攻就夠了,只有打 BOSS 才需要放大招!" 

執(zhí)行策略詳解

"哇!太神奇了!" 小王興奮地轉(zhuǎn)著椅子,"那個(gè)par 是什么意思啊?"

"這個(gè)啊,是 parallel 的縮寫(xiě),表示并行執(zhí)行。" 老張解釋道,"C++17給我們提供了三種執(zhí)行策略:

  • seq - 就像你以前寫(xiě)的那樣,按順序執(zhí)行
  • par - 并行執(zhí)行,適合CPU密集型任務(wù)
  • par_unseq - 并行加向量化,適合簡(jiǎn)單的數(shù)值計(jì)算"

小王聽(tīng)得目瞪口呆:"所以說(shuō),處理不同的任務(wù),就該選擇不同的'戰(zhàn)斗模式'咯?"

"沒(méi)錯(cuò)!" 老張神秘地眨眨眼,"就像打游戲要看怪物選擇武器一樣,處理簡(jiǎn)單的小數(shù)據(jù),就用seq 獨(dú)行俠模式;遇到需要大量計(jì)算的復(fù)雜任務(wù),就開(kāi)啟par 分身模式;如果是純數(shù)值計(jì)算這種簡(jiǎn)單粗暴的活兒,那就直接上par_unseq 終極模式,讓CPU的每個(gè)核心都嗨起來(lái)!" 

實(shí)戰(zhàn)示例

"誒~老張,我這還有個(gè)需求..." 小王撓撓頭,露出一副求知的表情,"要是我想對(duì)一大堆數(shù)據(jù)做批量計(jì)算,比如給所有商品打個(gè)折,有什么快速的方法嗎?"

老張放下他那冒著熱氣的咖啡杯,眼睛里閃過(guò)一絲智慧的光芒:"這簡(jiǎn)單??!就用咱們的并行版transform 唄!它就像是一個(gè)魔法復(fù)制機(jī)器 ??,不但能復(fù)制,還能在復(fù)制的時(shí)候順便改變數(shù)據(jù)。來(lái)看看這段魔法咒語(yǔ):"

std::vector<double> prices{/* 這里塞滿(mǎn)了商品價(jià)格 ?? */};
std::vector<double> discounted(prices.size());

// 召喚并行折扣魔法 ?
std::transform(std::execution::par,
    prices.begin(), prices.end(),
    discounted.begin(),
    [](double price) { return price * 0.8; }  // 施展八折魔法 ??
);

"看到?jīng)]?" 老張得意地轉(zhuǎn)了轉(zhuǎn)他的魔法棒(其實(shí)是他的簽字筆),"這段代碼就像是召喚了一群小精靈,它們同時(shí)出動(dòng),每個(gè)小精靈負(fù)責(zé)處理一部分價(jià)格,刷刷刷~ 一眨眼的功夫,所有商品就都打好折扣啦!比你一個(gè)一個(gè)手動(dòng)計(jì)算不知道快到哪里去了!"

小王的眼睛瞬間亮了起來(lái):"哇塞!這也太方便了吧!感覺(jué)就像是給程序開(kāi)了個(gè)外掛一樣!"

"沒(méi)錯(cuò)!" 老張笑著點(diǎn)點(diǎn)頭,"而且這個(gè)魔法特別靈活,不光是打折,你想對(duì)數(shù)據(jù)做任何批量處理都可以,比如計(jì)算平方、求對(duì)數(shù),甚至是更復(fù)雜的運(yùn)算,通通都不在話下!就是要記得,這么強(qiáng)大的魔法,最好是在數(shù)據(jù)量比較大的時(shí)候再用,不然就有點(diǎn)大材小用啦~" 

小王興奮地搓了搓手:"太棒了!這下我的數(shù)據(jù)處理要起飛咯~"

性能注意事項(xiàng)

"哎呀,等等!" 老張突然舉起他那冒著熱氣的咖啡杯,露出一副"我要傳授秘籍"的表情,"并行雖然是個(gè)好東西,但也不是什么時(shí)候都能派上用場(chǎng)的神器哦!"

小王正沉浸在并行的魔力中,聽(tīng)到這話立刻豎起了耳朵:"咦?這是為啥呀?"

老張神秘地笑了笑:"你想啊,就像組織一場(chǎng)派對(duì) - 叫上三五好友一起玩還挺熱鬧的,但要是就吃一塊小蛋糕,你還要發(fā)幾十個(gè)邀請(qǐng)、等大家到齊,那不是搞得太隆重了嘛!并行也是一樣的道理 - 啟動(dòng)線程要時(shí)間,線程之間互相打招呼也要時(shí)間,這些開(kāi)銷(xiāo)可不小呢!"

"??!我懂了!" 小王恍然大悟地拍了下桌子,"就像叫一群朋友來(lái)搬一個(gè)小箱子,光是組織大家來(lái)就累死了!"

"聰明!" 老張贊許地點(diǎn)點(diǎn)頭,"一般來(lái)說(shuō)啊,除非你的數(shù)據(jù)量像天上的星星一樣多(至少上萬(wàn)個(gè)吧),不然還真不如一個(gè)人慢慢來(lái)。畢竟擺好'獨(dú)行俠'的架勢(shì),有時(shí)候反而比召喚一支'復(fù)仇者聯(lián)盟'來(lái)得更實(shí)在呢!"

小王若有所思地摸著下巴:"這么說(shuō)的話,我得好好掂量掂量什么時(shí)候該放大招了!"

"就是這個(gè)理兒!" 老張開(kāi)心地喝了口咖啡,眼睛笑得像月牙兒一樣,"記住啊,程序優(yōu)化就像武功修煉,要講究個(gè)'恰到好處'。有時(shí)候,簡(jiǎn)單樸實(shí)的單線程反而是最佳選擇呢!" 

使用建議

"哎呀,差點(diǎn)忘了最重要的一點(diǎn)!" 老張突然轉(zhuǎn)過(guò)身來(lái),神秘兮兮地壓低聲音說(shuō),"要說(shuō)并行計(jì)算的終極秘訣,那就是容器的選擇特別重要!就像選武器一樣,用vector 這種連續(xù)存儲(chǔ)的容器,就像是揮舞一把鋒利的寶劍,干脆利!但要是用list 這種到處都是指針的容器,那就像是在用一把生銹的鈍刀,砍得你手都酸了~"

"原來(lái)如此!" 小王恍然大悟,趕緊掏出他那本寫(xiě)滿(mǎn)筆記的小本本,生怕漏掉任何一個(gè)重要細(xì)節(jié)。

老張看著小王認(rèn)真的樣子,欣慰地笑了:"記住啊,寫(xiě)代碼就像做菜,先把基本功練好才是王道。等你覺(jué)得程序慢得像蝸牛爬的時(shí)候,再考慮加上并行這個(gè)'秘制調(diào)料'也不遲!"

"好嘞!" 小王朝著老張的背影揮手致敬 ??,心里暗暗發(fā)誓要把今天學(xué)到的并行魔法好好消化。轉(zhuǎn)過(guò)頭來(lái),他的手指已經(jīng)在鍵盤(pán)上飛舞起來(lái),開(kāi)始了代碼重構(gòu)的冒險(xiǎn)之旅。

"等等!" 老張又探出頭來(lái),眨了眨眼睛,"記得多測(cè)試?。〔⑿杏?jì)算就像是駕馭一匹烈馬,看起來(lái)威風(fēng),但也要當(dāng)心別被甩下來(lái)!"

小王豎起大拇指:"放心吧,老張!我一定會(huì)從簡(jiǎn)單開(kāi)始,循序漸進(jìn)地馴服這匹并行'烈馬'的!"

小貼士 

(1) 記得包含<execution> 頭文件

(2) 根據(jù)編譯器可能需要鏈接并行庫(kù):

  • MSVC: 無(wú)需額外庫(kù)
  • GCC: 需要-ltbb 或 OpenMP
  • Clang: 支持有限,可能需要 TBB

(3) 并行執(zhí)行可能會(huì)改變?cè)靥幚眄樞?/p>

(4) Lambda 表達(dá)式要保證線程安全

更多實(shí)戰(zhàn)案例

"誒,老張!" 小王舉手提問(wèn)道,"我想知道除了剛才的那些,還有什么好用的并行算法呀?"

老張放下他那標(biāo)志性的程序員馬克杯,眼睛閃著智慧的光芒:"來(lái)來(lái)來(lái),讓我給你展示一些超級(jí)實(shí)用的并行魔法!"

基礎(chǔ)操作篇

首先是一些常見(jiàn)的基礎(chǔ)操作:

#include <execution>
#include <algorithm>
#include <vector>

// 準(zhǔn)備一些測(cè)試數(shù)據(jù) ??
std::vector<int> scores{
    /* 這里是學(xué)生成績(jī)數(shù)據(jù) */
}; 

// 1. 并行排序 - 給成績(jī)單排序 ??
// 可以快速對(duì)大量成績(jī)進(jìn)行排序
std::sort(
    std::execution::par,  // 開(kāi)啟并行模式
    scores.begin(), 
    scores.end()
);

// 2. 并行查找及格的同學(xué) ??
auto pass_score = 60;
auto it = std::find_if(
    std::execution::par,
    scores.begin(), 
    scores.end(),
    [pass_score](int score) { 
        return score >= pass_score; 
    }
);

"哇塞!這也太方便了!" 小王驚嘆道,"感覺(jué)代碼一下子變得好簡(jiǎn)潔!"

老張喝了口咖啡,神秘地笑了笑:"這還不是最厲害的呢!來(lái)看看這些并行算法的'終極大招'!想象一下,你是個(gè)老師,要統(tǒng)計(jì)一個(gè)年級(jí)上千名學(xué)生里有多少個(gè)學(xué)霸,用以前的方法,怕是要數(shù)到頭暈眼花。但有了并行版的count_if,就像是分身出好多個(gè)老師一起數(shù),效率蹭蹭往上漲!"

"再比如啊," 老張眨眨眼繼續(xù)說(shuō)道,"有時(shí)候系統(tǒng)出故障,不小心把一些同學(xué)的分?jǐn)?shù)記成負(fù)數(shù)了。要是一個(gè)一個(gè)改,那得改到什么時(shí)候去?但用并行版的replace_if,就像是召喚出一群小精靈,每個(gè)小精靈負(fù)責(zé)修改一部分?jǐn)?shù)據(jù),刷刷幾下就把負(fù)分都變成0分啦!"

老張舉起他那標(biāo)志性的馬克杯:"這就是并行算法的魅力 - 它不光能讓你的代碼看起來(lái)更優(yōu)雅,還能真真切切地幫你節(jié)省時(shí)間。就像是給你的程序裝上了一個(gè)'時(shí)間加速器' ,讓繁重的工作變得輕松愉快!"

// 3. 并行統(tǒng)計(jì) - 數(shù)一數(shù)優(yōu)秀生有多少 ??
auto excellent_count = std::count_if(
    std::execution::par,
    scores.begin(), 
    scores.end(),
    [](int score) { 
        return score >= 90;  // 90分以上就是優(yōu)秀
    }
);

// 4. 并行數(shù)據(jù)修正 - 把負(fù)分都改成0分 ?
std::replace_if(
    std::execution::par,
    scores.begin(), 
    scores.end(),
    [](int score) { 
        return score < 0;  // 找出負(fù)分
    }, 
    0// 替換為0分
);

小王聽(tīng)得入迷了:"這簡(jiǎn)直就像變魔術(shù)一樣!以前要寫(xiě)好多復(fù)雜的多線程代碼才能實(shí)現(xiàn)的功能,現(xiàn)在只要加個(gè)par 就搞定了!"

"沒(méi)錯(cuò)!" 老張得意地說(shuō),"現(xiàn)代C++就是這么神奇,它把復(fù)雜的并行計(jì)算都包裝得像施魔法一樣簡(jiǎn)單。不過(guò)記住啊,這些魔法雖然強(qiáng)大,但也要在數(shù)據(jù)量夠大的時(shí)候才能發(fā)揮威力。就像召喚神龍,要集齊七顆龍珠才行!"

高級(jí)操作篇

"哎呀,小王啊," 老張神秘兮兮地湊近了一點(diǎn),"剛才那些都是基礎(chǔ)操作,現(xiàn)在讓我們來(lái)點(diǎn)更刺激的!"

小王立刻來(lái)了精神,眼睛閃閃發(fā)亮:"快說(shuō)快說(shuō)!"

"想象一下,你是個(gè)班主任" 老張眨眨眼繼續(xù)說(shuō)道,"現(xiàn)在要把A班和B班的成績(jī)單合并,還得按分?jǐn)?shù)排序。用以前的方法,怕是要對(duì)著兩張表來(lái)回看,忙活半天。但有了并行版的merge,就像變魔術(shù)一樣簡(jiǎn)單!"

// 兩個(gè)班的成績(jī)單準(zhǔn)備好咯 ??
std::vector<int> class_a{/* A班的小可愛(ài)們的分?jǐn)?shù) */};
std::vector<int> class_b{/* B班的成績(jī)單 */};

// 施展合并魔法! ?
std::vector<int> merged(class_a.size() + class_b.size());
std::merge(
    std::execution::par,  // 召喚并行小精靈們
    class_a.begin(), class_a.end(),
    class_b.begin(), class_b.end(),
    merged.begin()
);

"但這還不是最厲害的呢!" 老張端起他那冒著熱氣的咖啡杯,"假設(shè)現(xiàn)在要計(jì)算期末總評(píng),每科都有不同的權(quán)重。要是手算,準(zhǔn)能算到頭昏眼花。但有了并行版的inner_product,就像有一群小精靈在幫你計(jì)算一樣!"

// 每科的權(quán)重都在這里 ??
std::vector<double> weights{/* 各科目的分量 */};

// 召喚加權(quán)計(jì)算魔法! ??
auto weighted_sum = std::inner_product(
    std::execution::par,
    scores.begin(), scores.end(),
    weights.begin(),
    0.0  // 從0開(kāi)始累加
);

"哦對(duì)了!" 老張突然想起什么似的一拍大腿,"還有個(gè)特別好玩的 - 要是想看看每個(gè)同學(xué)的成績(jī)累計(jì)到他這里是多少分,用inclusive_scan 一下子就搞定了!就像是給成績(jī)單施了個(gè)連加魔法!"

// 施展累計(jì)魔法! ??
std::vector<int> running_total(scores.size());
std::inclusive_scan(
    std::execution::par,
    scores.begin(), scores.end(),
    running_total.begin()
);

小王聽(tīng)得如癡如醉:"這簡(jiǎn)直太神奇了!感覺(jué)整個(gè)人都升級(jí)了!"

老張得意地抿了口咖啡:"不過(guò)啊,這些魔法也是要看場(chǎng)合的。就像召喚神龍,數(shù)據(jù)太少的時(shí)候反而會(huì)浪費(fèi)法力值。而且啊,最好用vector 這種整整齊齊的容器,不然就像是在雜亂的房間里施法,效果可就差遠(yuǎn)了!"

"明白!" 小王使勁點(diǎn)頭,生怕漏掉任何細(xì)節(jié),"這就是并行算法的終極奧義啊!"

"沒(méi)錯(cuò)!" 老張笑著站起身來(lái),"好好練習(xí)這些魔法,你也能成為并行世界的大法師!" 

小王看著老張遠(yuǎn)去的背影,心里暗暗發(fā)誓一定要把這些并行魔法練得爐火純青。畢竟,誰(shuí)不想讓自己的代碼插上翅膀,飛得更快呢? 

總結(jié)與展望 

通過(guò)這次并行算法的探索之旅,我們學(xué)到了:

(1) 并行算法的核心優(yōu)勢(shì) 

  • 充分利用多核CPU性能
  • 大幅提升數(shù)據(jù)處理速度
  • 代碼簡(jiǎn)潔易讀,使用方便

(2) 三種執(zhí)行策略的應(yīng)用場(chǎng)景 

  • seq: 適合小數(shù)據(jù)量順序處理
  • par: 適合CPU密集型大數(shù)據(jù)任務(wù)
  • par_unseq: 適合簡(jiǎn)單的數(shù)值計(jì)算操作

(3) 使用注意事項(xiàng)

  • 數(shù)據(jù)量要足夠大才值得并行
  • 優(yōu)先使用連續(xù)存儲(chǔ)的容器(如vector)
  • 確保并行操作的線程安全性
  • 根據(jù)實(shí)際性能測(cè)試選擇最佳策略

(4) 常用并行算法

  • 基礎(chǔ)算法: sort, find_if, count_if
  • 數(shù)值計(jì)算: reduce, transform
  • 高級(jí)操作: merge, inner_product, inclusive_scan

展望未來(lái),隨著硬件性能的提升和C++標(biāo)準(zhǔn)的發(fā)展,并行算法必將在現(xiàn)代C++編程中發(fā)揮越來(lái)越重要的作用。掌握這項(xiàng)"神器",讓我們的代碼插上騰飛的翅膀! 

責(zé)任編輯:趙寧寧 來(lái)源: everystep
相關(guān)推薦

2022-09-02 15:11:18

開(kāi)發(fā)工具

2023-12-18 10:11:36

C++17C++代碼

2010-11-08 10:20:18

2024-12-18 06:00:00

C++17C++

2023-09-16 18:54:38

Pythonfor循環(huán)

2010-02-06 15:31:18

ibmdwAndroid

2009-07-22 14:55:16

ibmdwAndroid

2016-12-08 22:39:40

Android

2017-05-09 08:48:44

機(jī)器學(xué)習(xí)

2022-06-10 08:17:52

HashMap鏈表紅黑樹(shù)

2012-02-29 00:49:06

Linux學(xué)習(xí)

2025-02-24 10:07:10

2024-12-19 11:30:00

C++17CTAD代碼

2024-12-27 12:00:00

C++17枚舉

2024-02-26 08:52:20

Python傳遞函數(shù)參數(shù)參數(shù)傳遞類(lèi)型

2023-10-13 08:23:05

2009-07-03 18:49:00

網(wǎng)吧綜合布線

2024-12-19 07:00:00

2011-10-26 20:47:36

ssh 安全

2024-06-07 08:51:50

OpenPyXLPythonExcel文件
點(diǎn)贊
收藏

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