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重新编译过程中如果遇到依赖问题需要逐一解决