2008-10-03 33 views
8

我一直在修補BSP樹一段時間,並且還在玩線程。當向BSP樹添加三角形時,出現了爲並行處理數據創建新線程的機會。我應該一起使用線程和遞歸嗎?

 
insert(triangle, bspnode) 
{ 
    .... 
    else if(triangle spans bspnode) 
    { 
    (frontpiece, backpiece) = plane_split(triangle, bspnode) 

    insert(frontpiece, bspnode.front) 
    insert(backpiece, bspnode.back) 
    } 
    .... 
} 

上面的兩個插入操作可以由兩個線程執行,並且由於它們不修改相同的數據,所以可以使用便宜的同步。

 
insert(triangle, bspnode) 
{ 
    .... 
    else if(triangle spans bspnode) 
    { 
    (frontpiece, backpiece) = split(triangle, bspnode) 

    handle = beginthread(insert(backpiece, bspnode.front)) 
    insert(frontpiece, bspnode.back) 
    if(handle) 
    { 
     waitforthread(handle) 
    } 
    else 
    { 
     insert(backpiece, bspnode.front) 
    } 
    } 
    .... 
} 

這種新方法試圖創建一個線程來完成並行操作,但如果線程不能創建應該不會失敗(這將簡單地恢復到原來的算法)。

這是一個完善的編程習慣,還是我使用線程不當?我一直無法找到關於這種技術的任何文獻。我喜歡它傾向於使用我的CPU到最完整的(2個內核),並且理論上可以擴展到任何數量的可用處理器。我不喜歡它在CPU和內存上可能會非常浪費。如果處理的某些部分上的東西外等待

回答

11

線程是偉大的(用戶輸入,I/O,其他的一些處理) - 這是等待可以繼續等待線程,而線程未在等待僞造先。

然而,對於處理密集型任務,比處理器的多個線程實際創建的開銷。看起來你的線程正在完成所有「CPU工作」,所以我堅持每個內核都有一個線程 - 測試以找到最佳數目。

創建的最大開銷是從上下文切換(凍結一個線程並加載下一個執行上下文),以及線程使用不同內存執行任務時緩存未命中(如果您的線程可以有效使用CPU緩存)。

+1

哦,他是RHYMES! :) HAHAH NICE! – Kiril 2008-12-01 17:05:30

2

你最好的選擇是創建一個線程池,然後用它「透明」添加節點。

例如,創建程序啓動2個線程,讓他們等待一個信號量或事件。當您添加節點時,您將數據彈出到隊列中,然後觸發信號量。這會喚醒將數據從隊列中彈出並執行處理的線程之一。 (確保對隊列的訪問是線程安全的 - 與關鍵部分完全同步是最好的)。

由於在將數據複製到隊列中並運行額外的線程時,應用程序的整體性能較慢,但如果您曾經在單個內核上運行,則現在將運行在2.它工作正常如果線程處理非常昂貴,那麼最好。

0

當然,例如,快速排序可以編程多線程很容易,並獲得多核心繫統,並在非多線程一些小的性能損失,一些大的性能提升。請記住,現在你需要兩次額外的開銷 - 一次是堆棧節省遞歸,一次是在線程上,所以如果你做了大量的遞歸,那麼它可能比非多線程方法更快地壓倒一個系統。

相關問題