1. 多核對於多線程來說會有多大的影響是否可以極大的提高多線程軟體的執行效率
對於採用並行編程模型實現的多線程程序,多核處理器在低負載的情況下能很有效地提高執行效率,對於同一個應用,如果採用串列的編程模型,那麼多核單核也就沒什麼區別了,如果該應用用並行演算法來實現,並且改演算法能將該應用的並行度提高到n,也就是說n個並行線程分別運行在n個核上時,不考慮n個線程之間的依賴性的話,本程序的速度就提高了n倍。
要利用多核的高吞吐能力,關鍵是有很好的並行演算法最大限度地開發對象問題內在的並行性。
關鍵:演算法本身的並行性。
2. 尋一篇多核程序設計的論文
We are dedicating all of our future proct development to multicore designs. We believe this is a key inflection point for the instry.
Intel President
Paul Otellini
Describing Intel』s future direction at the Developers Forum 2005
多核下的多線程程序設計與傳統的單核下的多線程程序設計有著一定的差別,在單CPU下,是多個線程在同一個CPU上並發地執行,而在多核下,則是由多個線程在多個核上並行地執行。
但是,目前的程序設計中對於多核的利用並沒有達到預期的效果。因此,為了能夠在多核的環境下設計出更適合多核系統的程序,則是一個挑戰。
要做到這一點,就必須將應用程序看做是眾多相互依賴的任務的集合,將應用程序劃分成多個獨立的任務,並確定這些任務之間的相互依賴關系,這就稱為分解(decomposition)。如下如示:
分解方式 設計 說明
任務分解 不同的程序行為採用不同的線程實現 常用於GUI應用程序
數據分解 多個線程對不同的數據塊執行相同的操作 常用於音頻、圖像處理和科學計算應用程序
數據流分解 一個線程的輸出作為另一個線程的輸入 應注意盡量避免延遲
任務分解:對應用程序根據其執行的功能進行分解的過程稱為任務分解(task decomposition)。根據這種方法,就能夠對眾多的獨立任務進行分類。如果其中兩個任務能夠同時運行,那麼開發人員就應該對其進行調度,形成二者之間的並行執行。
數據分解:數據分解也稱為數據級並行(data-level parallelism)。是將應用程序根據各任務所處理的數據而非按任務來進行分解的方法,即以數據為中心。一般而言,能夠按照數據分解方式進行分解的應用程序都包含多個線程,這些線程分別對不同的數據對象執行相同的操作。
數據流分解:在很多情況下,當對一個問題進行分解時,關鍵問題不在於採用一些什麼任務來完成這個工作,而在於數據在這些任務之間是如何流動的。這個時候就要採用數據流分解方式,如典型的生產者/消費者問題。
對於任務分解,有兩個需要注意的地方:
1. 劃分的對象是計算,將計算劃分為不同的任務
2. 劃分後,研究不同任務所需的數據,如果這些數據不相交,則證明劃分是成功的,如果數據有相當程序的相交,意味著要重新進行數據劃分和功能劃分。
如在一個氣候模型中,需要考慮到地表模型、水文模型與海洋模型等多種情況,那麼就應該將這幾種模型劃分成不同的任務,再分別進行並行地運算。
對於數據分解,劃分的對象是數據,可以是演算法的輸入數據、中間處理數據和輸出數據。在劃分時應該考慮到數據上的相應操作。
最簡單的情況下,比如對1000萬個數進行相加,可以對其進行數據上的分解,用多個線程來分別計算不同批次的數據。然後再將計算的中間數據加到一起成為最終的結果。
--------------------------------------------------------------------------------
scutan 回復於:2008-07-09 21:50:58
1. 線程過多
線程並不是越多越好,對於某個程序,如果線程過多反而會嚴重地降低程序的性能。這種影響主要在於:
將給定的工作量劃分給過多的線程會造成每個線程的工作量過少,因此可能導致線程啟動和終止的開銷比程序實際工作的時間還要多。
同時,太多並發線程的存在將導致共享有限硬體資源的開銷增大。如保存和恢復寄存器狀態的開銷、保存和恢復線程cache狀態的開銷、廢除虛存的開銷、線程聚集在一起等待獲取某個鎖。
怎樣解決這個問題:
限制可運行線程的個數
將計算線程與I/O線程分離開
使用已有的技術,如OpenMP,線程池等
2. 數據競爭、死鎖
死鎖,想必大家都很熟悉。這里談談一些簡單的避免死鎖的規則:
加鎖的順序是關鍵,使用嵌套的鎖時必須保證以相同的順序獲取鎖
防止發生飢餓:即這個代碼的執行是否一定會結束。
不要重復請求同一個鎖
越復雜的加鎖方案越有可能造成死鎖—設計應力求簡單
3. 競爭激烈的鎖
即使是正確使用鎖來避免數據競爭,但如果各線程對鎖的競爭很激烈,那麼也會引發性能問題。即很多個線程來競爭同一個鎖。在這個情況下,可以考慮將資源劃分成若干個部分,然後用彼此獨立的鎖分別保護各個部分。即合理地安排加鎖粒度的問題。在早期的linux內核中就使用了大內核鎖,現在已經把鎖給細劃到不同的子系統中去了。
如果一個數據結構被頻繁讀取但不被頻繁寫入,就可以使用讀寫鎖來解決競爭。
4. 線程安全函數
已有的一些函數並不是線程安全的,具體的線程安全函數可以參考APUE2上面的線程一章。
5. 存儲效率問題
目前,處理器的速度已經比存儲器快很多,一個處理器從內存中讀或寫一個值的時間內可以完成上百次的操作。因此,現在的程序往往受限於存儲器的瓶頸。
首先,可以通過節省帶寬,可以減少與存儲器的數據交換數量,要節省帶寬就要將數據壓縮得更加緊湊。
其次是cache的利用。可以減少數據在不同CPU的cache間的移動。CPU親合力(CPU Affinity)就是指在Linux系統中能夠將一個或多個進程綁定到一個或多個處理器上運行。一個進程的CPU親合力掩碼決定了該進程將在哪個或哪幾個CPU上運行,在一個多處理器系統中,設置CPU親合力的掩碼可能會獲得更好的性能。
在下面的例子中講解了如何利用將某個進程綁定以某個CPU上運行的實例。
http://linux.chinaunix.net/bbs/viewthread.php?tid=904906&extra=page%3D1%26amp%3Bfilter%3Ddigest
--------------------------------------------------------------------------------
scutan 回復於:2008-07-09 21:51:30
由於CPU運算速度的增長遠遠大於內存速度的增長,同時由於程序運行的局部性原理,所以現代計算機體系結構中引入了cache。
其實系統的存儲器本身就是一個層次結構,從寄存器->高速緩存->主存->本地磁碟->頒布式文件系統。
在下面的貼子中的一個文檔對cache方面講解得非常不錯,可以看看:
http://bbs.chinaunix.net/viewthread.php?tid=1022341&highlight=scutan
高速緩存的性能主要有以下幾個方面:
1. 高速緩存的大小:
當CPU接收到指令後,它會最先向CPU中的一級緩存去尋找相關的數據,如果未命中,則繼續向下一級的二級緩存中尋找。所以高速緩存越大,命中的機率也就越高。
2. 塊大小的影響
大的塊有利有弊,一方面,較大的塊能利用程序中可能存在的空間局部性,幫助提高命中率。不過,對於給定的高速緩存的大小,塊越大就意味著緩存行數越小,這會損害時間局部性比空間局部性更好的程序中的命中率。同時,因為塊越大,傳達時間也就越長。
3. 相聯度的影響
較高的相聯度的優點的降低了高速緩存由於沖突不命中出現抖動的可能性。不過,較高的相聯度會造成較高的成本。
4. 前端匯流排的影響
現在的CPU技術發展很快,運算速度提高很大,而足夠大的前端匯流排可以保障有足夠的數據供給CPU,較低的前端匯流排將無法供給足夠的數據給CPU,限制了CPU性能的發揮。
最後談談程序性能優化的相關內容。
對於程序性能的優化,首先應該考慮的架構以及演算法這兩方面的優化,最後再來考慮下面所講述的這些優化。
消除連續的函數調用
消除不必要的存儲器引用
通過展開循環降低循環開銷
提高並行性
重新排列循環以提高空間局部性
讓最常運行部分運行得更快
參考資料:
[1]. John L. Hennessy, David A. Patterson. 計算機體系結構:量化研究方法. 第4版
[2]. Shameem Akhter, Jason Roberts. 多核程序設計技術—通過軟體多線程提升性能
[3]. Randal E. Bryant, David O』Hallaron. 深入理解計算機系統
[4]. Daniel P.Bovet, Marco Cesati. 深入理解Linux內核 第3版
http://www.chinaunix.net/jh/23/1193971.html
我抄的 自己拿回去看看
3. 多核編程與單核編程的區別
多核對於單核的好處是可以真正地同時處理多件事情,因此如果程序想要在多核CPU上獲得更好的性能的話,使用多線程技術是必需的。但是採用多線程涉及到線程間數據同步的問題,程序員必須在線程間協調好對數據的訪問和處理。
不過我覺得多核編程與單核編程的區別並不是指線程同步問題,因為單核編程同樣可以使用多線程,同樣需要面對線程同步的問題。同樣的代碼不經過特別優化,均可以在多核CPU和單核CPU上運行得很好,只不過運行效率不同罷了。
所以我覺得多核編程和單核編程的區別在於對多線程技術需求的迫切程度。如果程序針對多核環境來編程,那麼必然要採用多線程技術,以獲得更好的性能;如果程序只針對單核環境,那麼對多線程並不是那麼敏感,但如果它採用了多線程,一旦在多核環境運行,它也能獲得性能的提升。
4. C語言中的MPI編程和多線程有什麼區別,MPI編程中針對的是一台電腦多核還是多台電腦謝謝!
MPI(MPI是一個標准,有不同的具體實現,比如MPICH等)是多主機聯網協作進行並行計算的工具,當然也可以用於單主機上多核/多CPU的並行計算,不過效率低。它能協調多台主機間的並行計算,因此並行規模上的可伸縮性很強,能在從個人電腦到世界TOP10的超級計算機上使用。缺點是使用進程間通信的方式協調並行計算,這導致並行效率較低、內存開銷大、不直觀、編程麻煩。OpenMP是針對單主機上多核/多CPU並行計算而設計的工具,換句話說,OpenMP更適合單台計算機共享內存結構上的並行計算。由於使用線程間共享內存的方式協調並行計算,它在多核/多CPU結構上的效率很高、內存開銷小、編程語句簡潔直觀,因此編程容易、編譯器實現也容易(現在最新版的C、C++、Fortran編譯器基本上都內置OpenMP支持)。不過OpenMP最大的缺點是只能在單台主機上工作,不能用於多台主機間的並行計算!如果要多主機聯網使用OpenMP(比如在超級計算機上),那必須有額外的工具幫助,比如MPI+OpenMP混合編程。或者是將多主機虛擬成一個共享內存環境(Intel有這樣的平台),但這么做效率還不如混合編程,唯一的好處是編程人員可以不必額外學習MPI編程。
5. 我想精通C語言編程,求高手指導學習方案。(比如C如何實現多線程,和多核程序設計等等)
想精通C就必須要了解底層知識,尤其是編譯原理,當你自己用C做出了一款C語言編譯器,基本可以說是精通C了(編譯器通常分兩部分,其中一部分是與CPU相關的驅動程序,這個可以直接用現成的,但語法分析以及語義分析之類的的要自己寫)。還有你問C如何實現多線程,我不太確定是什麼意思?你是想用C程序通過調用現有的線程庫來實現多線程編程還是想問如何用C現實出多線程的過程(也就是線程庫的製作)?前者隨便網上一搜就有一堆方法,後者基本只能在Linux上做,看看Linux內核中有關多線程實現的源代碼就差不多了(建議先讀一讀Linux內核設計與實現第3版再看代碼)
6. 2.3.4 多線程程序在多核和單核上運行的不同
鎖:在單核上,多個線程執行鎖或者臨界區時,實際上只有一個線程在執行臨界區代碼,而核心也只支持一個線程執行,因此不存在沖突。如果某個線程持有鎖,那麼只是其他線程不會被調度到CPU上執行,影響的只是持有和釋放鎖的時間,處理器時刻在運行著。但是在多核上運行時,鎖或臨界區會導致其餘處理器空閑而只允許一個處理器執行持有鎖的那個線程,這是一個串列的過程,會影響性能。
負載均衡:在單核上不用考慮負載均衡,因為各個線程輪流執行,當一個線程執行完時,便會執行另一個線程,不存在線程等待問題。即使各個線程的任務非常不平衡,也不會影響總執行時間。而在多核上執行時,此時最終時間由運行時間最長的線程決定。
任務調度:單核上,任務調度完全是操作系統的工作,無須軟體開發人員干預,通常有時間片輪轉、優先順序演算法等。而在多核上運行時,軟體開發人員要合理地在核心間分配任務,以盡量同時結束計算(此時任務調度的工作已經從操作系統轉移到了軟體開發人員)。
程序終止:在多線程環境中,何時終止程序就變得復雜,因為程序終止時需要確定各個線程都已經計算完成。幸運的是,多線程庫通常都提供了對應的函數。在多機編程上,這個問題可能會變得非常復雜。
7. 多核多線程技術的內容簡介
《多核多線程技術》就多核體系結構、晶元發展與系統軟體,多性能並行程序,多線程程序的性能調優方法,多線程編程方法以及編程中的常見問題等作了綜合講述,處處體現了多線程編程理念與綜合應用能力的培養。全書深入淺出,適合廣大程序員和IT從事人員使用。
8. 關於多線程編程和CPU多核多線程的關系
原則上只要線程數不多於CPU核心數,會把各個線程都分配一個核心,不需分片,而當線程數多於CPU核心數時才會分片。事實上目前的計算機系統正常情況下線程數都是遠遠多於CPU核心數的,所以一般都要分片,以允許所有線程並發運行。
9. VC++ 多線程編程怎麼充分利用多核CPU,並驗
python由於GIL的關系,python的多線程並沒有發揮多核的作用,這些線程都是在在單核上跑的 所以要想發揮多核的作用,就需要使用多進程,盡可能的在每一個CPU核心上分配到一個python進程。
所以要想跑滿多核CPU就得多進程多線程互相結合
10. 多核編程和多線程編程有什麼區別
有區別,多核編程是如何高效利用CPU去處理事務
多線程編程是 如何有效的處理事務。(個人理解,僅供參考~~)
一個是針對CPU,一個是針對事物本身