(1) 首先進(jìn)行線程的任務(wù)分割
為了優(yōu)化處理過程,我們需要將原本每個(gè)像素都需要執(zhí)行的“發(fā)射主射線(primary ray)并調(diào)用castRay()函數(shù)以著色像素”的任務(wù)分配到N個(gè)不同的線程中。這個(gè)過程中,對場景(Scene)的像素處理,即按Width和Height逐行逐列進(jìn)行渲染的操作,可以通過三種方式進(jìn)行線程劃分:一是依據(jù)行來劃分;二是依據(jù)列來劃分;三是將場景劃分為多個(gè)M行N列的區(qū)域,每個(gè)區(qū)域分配給一個(gè)線程。
(2) 構(gòu)建線程執(zhí)行的任務(wù)函數(shù)
基于原始代碼中對場景像素的逐行逐列處理邏輯,我們需要設(shè)計(jì)一個(gè)或多個(gè)線程可以執(zhí)行的函數(shù)。這個(gè)函數(shù)的輸入應(yīng)當(dāng)能夠定義每個(gè)線程需要處理的像素行范圍,這個(gè)范圍可以通過兩個(gè)參數(shù)ymin和ymax來界定。
(3) 實(shí)現(xiàn)并行化函數(shù)調(diào)用
此步驟與原始代碼的執(zhí)行方式有顯著差異,因?yàn)槲覀儗⒉捎枚嗑€程并行處理的方式來代替原來的串行處理。具體來說,就是為每個(gè)線程分配相應(yīng)的行范圍(或列范圍、區(qū)域范圍),并調(diào)用在步驟(2)中構(gòu)建的函數(shù)來執(zhí)行。特別重要的是,在所有線程啟動(dòng)后,需要確保主線程(或任何其他等待線程)在繼續(xù)執(zhí)行之前等待所有工作線程完成。這通常通過調(diào)用每個(gè)線程的join()*來實(shí)現(xiàn),以避免在程序結(jié)束前出現(xiàn)線程未處理完畢導(dǎo)致的異常。
(4) 確保線程正確同步
在執(zhí)行多線程程序時(shí),務(wù)必注意每個(gè)線程的正確同步。通過調(diào)用join()*,可以確保主線程在繼續(xù)執(zhí)行之前等待所有子線程完成它們各自的任務(wù)。這一步對于程序的正確性和穩(wěn)定性至關(guān)重要,因?yàn)槲磮?zhí)行join()或detach()的線程在程序結(jié)束時(shí)可能會(huì)導(dǎo)致資源未釋放或程序異常退出。
(5) 渲染過程完成
當(dāng)所有線程都完成了它們的任務(wù)并正確同步后,渲染過程即告結(jié)束。此時(shí),可以通過調(diào)用UpdateProgress()函數(shù)來更新渲染進(jìn)度,并向其傳遞值1,表示渲染過程已完成*。這樣,用戶就可以通過某種形式的進(jìn)度條或提示看到渲染操作的成功完成。