A. linux單進程如何實現多核cpu多線程分配
linux下的單進程多線程的程序,要實現每個線程平均分配到多核cpu,主要有2個方法
1:利用linux系統自己的線程切換機制,linux有一個服務叫做irqbalance,這個服務是linux系統自帶的,默認會啟動,這個服務的作用就是把多線程平均分配到CPU的每個核上面,只要這個服務不停止,多線程分配就可以自己實現。但是要注意,如果線程函數內部的有某個循環,且該循環內沒有任何系統調用的話,可能會導致這個線程的CPU時間無法被切換出去。也就是占滿CPU現象,此時加個系統調用,例如sleep,線程所佔的CPU時間就可以切換出去了。
2:利用pthread庫自帶的線程親和性設置函數,來設置線程在某個CPU核心上跑,這個需要在程序內部實現。同時注意不要和進程親和性設置搞混淆了
intpthread_setaffinity_np(pthread_tthread,size_tcpusetsize,
constcpu_set_t*cpuset);
intpthread_getaffinity_np(pthread_tthread,size_tcpusetsize,
cpu_set_t*cpuset);
從函數名以及參數名都很明了,唯一需要點解釋下的可能就是cpu_set_t這個結構體了。這個結構體的理解類似於select中的fd_set,可以理解為cpu集,也是通過約定好的宏來進行清除、設置以及判斷:
//初始化,設為空
voidCPU_ZERO(cpu_set_t*set);
//將某個cpu加入cpu集中
voidCPU_SET(intcpu,cpu_set_t*set);
//將某個cpu從cpu集中移出
voidCPU_CLR(intcpu,cpu_set_t*set);
//判斷某個cpu是否已在cpu集中設置了
intCPU_ISSET(intcpu,constcpu_set_t*set);
B. C++ openmp並行程序在多核linux上如何最大化使用cpu
openmp並行程序在多核linux上最大化使用cpu的方法如下:
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
#include<time.h>
intmain()
{
longlongi;
longdoublesum=.0;
longdoublesec=.0;
//Multi-threadcomputestart
clock_tt1=clock();
#pragmaompparallelfor
for(i=0;i<1000000000;i++)
{
sum+=i/100;
}
clock_tt2=clock();
sec=(t2-t1);
//sec=(t2-t1);
printf("Programcosts%.2Lfclocktick. ",sec);
exit(EXIT_SUCCESS);
}
以上代碼中,#pragma omp parallel for
這一行的作用即是調用openmp的功能,根據檢測到的CPU核心數目,將for (i = 0; i < 1000000000; i++)這個循環執行過程平均分配給每一個CPU核心。
去掉#pragma omp parallel for這行,則和普通的串列代碼效果一致。
注意,要使用openmp功能,在編譯的時候需要加上-fopenmp編譯參數。
以下是兩種編譯搭配兩種代碼出現的4種結果,可以很直觀地看到效果:
1、代碼里含有#pragma omp parallel for,編譯參數有-fopenmp
Endys-MacBook-Pro:Desktop endy$ vi test.c
Endys-MacBook-Pro:Desktop endy$ gcc-6 test.c -o test -fopenmp
Endys-MacBook-Pro:Desktop endy$ ./test
Program costs 50202611.00 clock tick.
2、代碼里含有#pragma omp parallel for,編譯參數沒有-fopenmp
Endys-MacBook-Pro:Desktop endy$ gcc-6 test.c -o test
Endys-MacBook-Pro:Desktop endy$ ./test
Program costs 4068178.00 clock tick.
3、代碼里沒有#pragma omp parallel for,編譯參數有-fopenmp
Endys-MacBook-Pro:Desktop endy$ vi test.c
Endys-MacBook-Pro:Desktop endy$ gcc-6 test.c -o test -fopenmp
Endys-MacBook-Pro:Desktop endy$ ./test
Program costs 4090744.00 clock tick.
4、代碼里沒有#pragma omp parallel for,編譯參數沒有-fopenmp
Endys-MacBook-Pro:Desktop endy$ vi test.c
Endys-MacBook-Pro:Desktop endy$ gcc-6 test.c -o test
Endys-MacBook-Pro:Desktop endy$ ./test
Program costs 4170093.00 clock tick.
可以看出,只有在情況1下,openmp生效,其他3種情況下,均為單核運行,2、3、4結果較為接近,而1的運行結果大約相差25%。
值得注意的是,使用多核心的case 1竟然比單核的其他3種case慢了25%,原因是在這種單一的循環運算中,並行分配CPU任務的指令比直接執行下一個循環指令的效率更低。所以並不是用並行運算就一定能夠提高運算效率的,要根據實際情況來判斷。
C. linux為什麼可以支持多個架構的CPU
不同架構硬體的linux實際上不是一種系統,比如針對IBM power的Power Linux,這個不能安裝到x86架構的硬體上去,同樣,反過來也不行,因為OS的指令需要最終是解釋成硬體可以理解的指令然後去執行,不同架構的硬體的指令集是不同的,IBM的power屬於RISC架構,使用RISC指令集。你自己去看看各個發行版的linux,都是區分硬體架構的,比如針對HP小型機的IA64版本,針對amd64位的x86_64版本,還有針對arm架構的版本,不存在一種可以兼容多種架構的發行版,而且,上面可以運行的程序也是不一樣的,我拿oracle資料庫舉例,這對不同架構的版本也是區分的,你可以看看下圖,說到底,即便都叫linux,不同硬體上面的linux並不是一樣的東西。
D. linux 多線程cpu運行時間
1、程序(linux環境下)運行自己寫的線程之後,程序卡頓
2、查看程序(linux環境下)運行資源消耗 top命令,CPU佔用率達到了98%
問題分析
1、反復查看線程中程序執行步驟,並沒有高耗CPU的操作
2、查看程序優化的網路經驗,優化一些演算法,但也不能CPU佔用率達到98%
3、最後多次查看線程概念、原理得出結論:
線程就是一個死循環,線程要有跳出語句,要預留出其他程序的運行的時間片
解決:
while(1)中加入sleep(),防止一直佔用CPU
---恢復內容結束---
E. linux為什麼可以支持多個架構的CPU
任何操作系統(包括DOS、Windows、Unix、Linux等等),都可以做到支持所有架構的處理器,只要針對各種架構的處理器重新進行編譯和優化、調整即可。因為系統編程都是用高級語言編寫的,編寫時都是不怎麼依賴於硬體特性,編寫後再針對不同架構的處理器的機器語言進行專門的編譯即可使用。比如,現在的Windows10就已經可以支持X86之外的處理器了,安卓系統(根植於Linux)早已在X86系統上跑的很歡。即使是蘋果的iOS系統,如果蘋果開放授權,照樣可以用於各類架構的處理器,無非蘋果願不願意而已。
F. 請問運行於不同CPU構架的linux,它們的軟體可以通用嗎
以上回答中jiangtao9999的比較靠譜兒。
是這樣:
1、Linux下的軟體幾乎都是c語言的;
2、如果你學過C語言,找找書應該有這樣一個概念:ANSI C,這個是一個C語言的標准,比如printf這個函數就屬於標准庫(也就是符合ANSI標準的)函數
3、假如你編寫了一個軟體,代碼中僅僅包含ANSI的庫函數,那麼沒有問題,只要是支持C語言的平台,都能正常運行,即:編寫了一個簡簡單單的helloworld到哪裡編譯運行都沒有問題。
【前提是:】編譯再運行,不編譯就運行是不可以的,比如printf函數在各種架構上的實現方式是不可能相同的,所以需要在arm的編譯器上再編譯一遍才可以。否則運行不了。
有的軟體平台可以不用編譯,直接運行,比如jiangtao9999說的java、Python什麼的,Java可以實現「一次編譯,滿哪運行」什麼的,而Python則是有了.py源代碼就可以無敵了,使用的時候不用你去執行編譯命令,直接執行即可。arm上實現這兩種語言都是很容易的——下載源代碼、編譯、安裝即可。
4、不同架構的Linux平台都要實現一個編譯器,這是很重要的,有了編譯器,才可以從源代碼安裝軟體。
5、使用非ANSI庫中的函數需要該Linux包含這個函數的實現,否則,編譯後的連接將不通過,比如一個軟體使用了GTK來實現圖形用戶界面,那麼就需要系統中包含了gtk的庫函數,這就叫依賴,安裝軟體,首先要解決依賴,依賴有時候解決起來很麻煩,所以軟體開發過程中盡量減少依賴,這樣方便安裝。
6、tar.gz這種格式的軟體包有可能是源代碼,有可能是可執行文件(這是因為那隻是一個壓縮包,內容是什麼不一定),這兩者不同。很多軟體以tar.gz格式發布源代碼,而qq的Linux版本屬於可執行文件,在幾乎所有Linux平台下面直接雙擊或者通過命令就可以使用。
7、如果你使用的是rpm包或者deb包或者是tar.gz文件包中可執行文件形式的軟體包,而不是tar.gz這種形式的源代碼,你需要使用相應的軟體包管理器安裝就行,
但這不意味著arm版本的deb和x86版本的deb文件是通用的,你能這樣用是因為所有的使用x86機器的軟體經過編譯或者交叉編譯(在arm平台上編譯x86平台上的軟體就叫交叉編譯)以後,運行於幾乎完全一樣的統一的平台上,實現軟體和系統的無縫對接,方便了用戶——一方面可以不用浪費編譯的時間,主要還是方便了那些不會編譯軟體的人。
8、我也正在學習Linux,所以很多地方不太對,這只是我現在的一些理解。jiangtao9999說的主要是和匯編有關,如果代碼的實現主要是在c語言水平,那麼就會由編譯器屏蔽掉指令集和寄存器什麼的。
9、要是在網路回答的答案能改改就好了,這樣錯誤就會少一點。
10、重新羅嗦一遍:
1在不重新編譯源代碼的情況下,x86下linux的軟體不可以運行於arm構架的Linux,即使運行也會奇卡。
2和在編譯是否時為X86的CPU構架優化了編譯無關。(把我問迷糊了,估計是無關)
3軟體在編譯時是否為X86的CPU構架而優化主要看作者了,資料可以參看http://www.gentoo.org/doc/zh_cn/gcc-optimization.xml
4和不同的安裝包格式有一定關系
5tar.gz格式的軟體包不能保證在不同架構的Linux都能運行
6在arm的linux安裝時解決依賴以後,乳溝編譯通過基本是沒什麼問題的
7不是所有源代碼在arm和x86下編譯一下就可以了,還需要做一些努力
8有源代碼可以對遇到的不通過的問題逐一解決,理論上可以實現所有軟體都能運行
9重新編譯過程中如果遇到依賴問題需要逐一解決