| 蓝色键盘 回复于:2003-05-06 17:38:51
|
系统资源在多cpu环境中是由OS来均衡调度的。
代码最终是一些指令,一般不能够在代码中指定让那个cpu来执行。
代码可以做一些优化,但是这种优化也不是分配cpu资源。
|
| 无双 回复于:2003-05-06 17:54:01
|
使用多线程
这样系统调度时可以同时执行两个线程
单线程的话系统没有办法实现分配到多CPU
|
| magicercn 回复于:2003-05-06 18:14:18
|
谢谢二位斑竹。
[size=18:a75dc72e0d][color=blue:a75dc72e0d]有很多软件产品都有提供一个配置文件,可以配置其对应的CPU个数,以充分利用系统资源。我还想问一下,除了多线程还有其他的办法么?
我曾经做过一个项目,系统配置了10个CPU,项目的组织考虑到了并发操作的重要性,也使用了多线程技术,但根据观察,程序运行时,只有三、四个CPU在跑,其他的都在休眠状态,(注:系统保证绝对没问题),所以我很困惑[/color:a75dc72e0d][/size:a75dc72e0d]
|
| diablocom 回复于:2003-05-06 18:22:34
|
你说的可配置的东西,那是一些大型的产品能做到的,不如说tuxedo的负载均衡等等。
让哪个CPU去工作,我们写的一般的代码我觉得无法实现。这个是有OS决定的。
再说了,2,3个CPU能完成的工作,为什么要让10个CPU去完成呢?
你可以做一个终极的测试,在你OS允许的范围内并发很多进程,也许那些休眠的CPU会work的。
|
| 无双 回复于:2003-05-06 18:23:05
|
是在什么系统上
solaris上吗
许多平台都有线程并发度限制
如solaris的pthread_setconcurrency
另外也可能还有其它方面原因
我等会找找看
|
| 无双 回复于:2003-05-06 18:27:55
|
另外看看编译选项上有没有什么可以设置的
找了资料
但是没有找到什么有用的
|
| 蓝色键盘 回复于:2003-05-06 18:47:28
|
编译选项上面好像没有什么特殊的选项,但是有一些指示行的选项,例如让某个局部变量成为寄存器变量。
如果是多cpu,但是在系统运行的时候,仍然存在idle的话,要么是系统没有达到启动另外一个cpu执行的程度,要么程序没有实现的很均衡。
不知道哪位知道informix中对于虚拟cpu的负载均衡是怎么实现的?
|
| JohnBull 回复于:2003-05-07 13:01:03
|
不能使用多线程,而应该使用多进程。
因为线程之间需要内存的共享,所以任何一个精神正常的人在设计操作系统的时候,都不会把同一个进程的多个线程分布到多个CPU中实现,否则线程间的数据共享会让总线效率剧烈下降。
一般来说,操作系统是以进程为单位进行CPU分配的。
|
| 无双 回复于:2003-05-07 13:10:25
|
对楼上看法有点疑问
就是操作系统
在同一时刻只保存一个进程的映像在运行
而不是多个进程的映象运行
这是以前看minix系统原理时看到的
我想就是多CPU的话
管理方法也一样吧
|
| 无双 回复于:2003-05-07 13:12:53
|
我不知道我的理解是不是有错
因为是以前看折
|
| 无双 回复于:2003-05-07 13:18:14
|
http://unit.cug.edu.cn/wlzx/wlfw/LINUX_UNIX/Kernel/LinuxKernel/chapter4/chapter4.htm
系统中最重要的资源是 CPU, 通常只有一个。 作为一个多重处理操作系统, Linux 的
目标是让系统中的每个 CPU 上面始终有一个进程在执行, 以充份利用 CPU。 如果进程
数多于 CPU 数(通常总是这样), 多余的进程必须等待有 CPU 空闲下来才能运行。
谢谢JohnBull 兄指点
是我理解错了
|
| magicercn 回复于:2003-05-09 16:02:12
|
我不同意JohnBull兄的观点。
不是不能使用多线程,而是多线程用得好不好的问题。
正如蓝色键盘所说的,是程序没有实现得很均衡。
昨天我看到一本书上讲了这个问题。在这里与大家共享
其实我们讨论的问题属于程序可扩展性问题,即服务器性能的提高与CPU数量的增加成正比。但考虑到Context Switch与别的额外开销,服务器性能要达到随CPU数目翻倍而成倍增长是不可能的。最理想的结果是使服务器性能最大限度的增加。
一般的CPU都提供了Cache功能。我们设计的程序最好能利用到Cache,其次是RAM,然后是磁盘。一般在每个CPU中只使用一个线程做处理。我们尽量把相同或相近的操作放在一起来执行,这样当指令和数据被从磁盘中加载到Cache中后,就可以重复调用,不再需要跑到磁盘上去调,从而极大地提高程序的性能。
|
| 蓝色键盘 回复于:2003-05-09 16:37:34
|
一般的CPU都提供了Cache功能。我们设计的程序最好能利用到Cache,其次是RAM,然后是磁盘。一般在每个CPU中只使用一个线程做处理。我们尽量把相同或相近的操作放在一起来执行,这样当指令和数据被从磁盘中加载到Cache中后,就可以重复调用,不再需要跑到磁盘上去调,从而极大地提高程序的性能。
谢谢你把结果拿来大家一起讨论!
你看到的是单CPU中,进程调度的处理情况。有机会你去找找多CPU体系结构中是怎么实现的。然后把结果告诉大家!
|
| 无双 回复于:2003-05-09 18:09:04
|
许多系统上线程也是使用进程的数据结构实现的(当然有点区别,称为轻量进程)
所以我想这线程和进程是一样
我以前操作系统看的现在都快忘记了
回去补一补
|
| cnufo 回复于:2005-01-10 01:47:14
|
插个嘴请教一下
我要对900多个文件排序,每个文件200万行左右,总行数在1。8亿
开了十个进程排序竟然要9个小时
我直接用sort命令排序的
单个执行sort 一个文件才11分钟
为什么并行后平均下来一个进程一个小时只排序一个文件呢?
|
| cnufo 回复于:2005-01-10 01:56:43
|
以下是我实现的代码,请帮忙看看问题在哪里?
如何优化,9个小时实在是太久了!
[code:1:8ecfc7eb30]
while(gi_process[i]!=0)
{
if(fork() == 0)
{
char cdrsourceid;
int i_cdrsourceid;
/*LoginToDB();*/
LoginToDB("BILL_USER_NAME","BILL_PASS_NAME","CONNECT_STRING");
gi_process_id = gi_process[i];
/*MonitorChild(gi_process_id,"分拣子进程开始运行");*/
GetPreFileName();
while( OpenCdrFile( &cdrsourceid ) )
{
i_cdrsourceid = atoi(&cdrsourceid);
if( atoi(ptr_shm_drecs+i_cdrsourceid*10))
{
sprintf( sort_originalfile, "%s/%d_D%04d.SORT" , rgTempFileDir , i_cdrsourceid , preproc_batch);
sprintf( sort_resultfile, "%s/%d_D%04d.TMP" , rgTempFileDir , i_cdrsourceid, preproc_batch);
sprintf( sort_comm, "sort -T /bill -k 2 %s > %s" , sort_originalfile, sort_resultfile );
sprintf( rm_comm, "rm %s", sort_originalfile);
MonitorChild(gi_process_id,sort_comm);
if( system( sort_comm ) != -1)
{
if( system( rm_comm ) != -1 )
{
printf("processid= %d,sort_originalfile=%s\n",gi_process_id,sort_originalfile);
continue;
}
else
{
printf("Error occur while deleting the file %s\n",sort_originalfile);
ChildError();
return -1;
}
}
else
{
printf(" Error occur while sorting the file %s\n", sort_originalfile);
ChildError();
return -1;
}
}
}
DestroyPreFileNameTbl();
exit(0);
}
else if(i_fork<0)
{
perror("fork failed\n");
system("/bill/prog_source/dispatch/killdisp");
}
i++;
}
[/code:1:8ecfc7eb30]
|
| 黄山松 回复于:2005-01-10 09:40:50
|
[quote:f625e3cd08="蓝色键盘"]一般的CPU都提供了Cache功能。我们设计的程序最好能利用到Cache,其次是RAM,然后是磁盘。一般在每个CPU中只使用一个线程做处理。我们尽量把相同或相近的操作放在一起来执行,这样当指令和数据被从磁盘中加载到Cache?.........[/quote:f625e3cd08]
不太懂如何设计程序才能利用cache?能否请版主将明白些吗?
cache的使用是程序来控制的吗?
|
| 黄山松 回复于:2005-01-10 09:45:14
|
除了大侠说的这么多,还有比较重要的是在驱动的程序设计中要注意的一些,比如针对中断处理,通常会配合软中断, tasklet, 下半部来处理, 此时只能用软中断或tasklet,万不可用下半部.
|
| superdoctor 回复于:2005-01-10 10:52:46
|
[quote:3bd1c72370="黄山松"]除了大侠说的这么多,还有比较重要的是在驱动的程序设计中要注意的一些,比如针对中断处理,通常会配合软中断, tasklet, 下半部来处理, 此时只能用软中断或tasklet,万不可用下半部.[/quote:3bd1c72370]
即使不能直接操纵cache但是我们都知道cache里面会装些什么啦,所以程序设计还是可以间接的控制一下的
下半部是什么?"万不可用下半部"听着有点象下半身 8)
真心请教
|
| 黄山松 回复于:2005-01-10 11:46:36
|
[quote:3fec69402b="superdoctor"]
即使不能直接操纵cache但是我们都知道cache里面会装些什么啦,所以程序设计还是可以间接的控制一下的
下半部是什么?"万不可用下半部"听着有点象下半身 8)
真心请教[/quote:3fec69402b]
先举个例子,对于一个中断处理:
需要从I/O读取数据,然后进行处理.你可以:
1.在中断处理中读取数据并处理,这样会影响中断响应时间,肯定不好:)
2.中断处理中读取数据放到缓冲区,然后添加一个task到tasklet或者添加一个BH
BH bottom half顾名思义就是后处理的,相对应的中断处理中的动作就是上半部分了:)
区别:(针对10个CPU的多处理系统)
软中断SOFTIRQ:
一个软中断可以并发执行在多个CPU上,此时软中断处理函数要是可重入的,而且对于用到的数据要用spin加以保护
tasklet:
建立在SOFTIRQ之上的
对于有10个task要处理的任务队列,内核会这么处理1task/1cpu,并行处理,但在一个CPU上运行了的task不可以转到另外一个CPU,必须要在该CPU上处理知道结束才可以.
BH
建立在SOFTIRQ之上
对于10个BH要处理的情况,必须是一个BH一个BH的顺序的在某个CPU上处理,也就是说只要有一个BH被处理了,其它的BH必须要等这个BH处理结束后才能处理.
哪个更为适合多CPU系统,一看就知道了吧:)
平常用的比较多的是tasklet.软中断没用过,一知半解,真心期待高手不吝赐教啊,先谢了:)
|
| gvim 回复于:2005-01-10 12:34:26
|
[quote:19b3abce30="黄山松"]
不太懂如何设计程序才能利用cache?能否请版主将明白些吗?
cache的使用是程序来控制的吗?[/quote:19b3abce30]
cache是os和cpu硬件配合管理的。
在多cpu内cache不一致的时候,cpu系统总线检测cache的改变信号,然后产生无命中的信号,以中断方式传递给os,清洗脏数据,包括L1,L2两级缓存,都会有系统总线的cache监听信号。如果读/写的数据长度和cache长度不符合,os还必须注意读/写数据的完整性,这个os也不能参与,只能适当的调整读出的位数为正确的数据长度。
cache查找速度和实现有关,如果是全路组方式,查找效率最高,但是冲突也会增加。
还有很多。。。。
所以,cache对软件包括os,都可以说是透明的。那么在程序员级能做的,无非就是优化一下数据长度,使之符合cache厂的,或者再进一步优化一下指令序列,配合cpu的U、V流水线的同步执行。
要吃饭了,其余的还没有想到。
|
| JohnBull 回复于:2005-01-10 22:47:13
|
[quote:92ed7b3c8f="gvim"]
cache是os和cpu硬件配合管理的。
[/quote:92ed7b3c8f]
cache是cpu硬件管理的。
[quote:92ed7b3c8f="gvim"]
在多cpu内cache不一致的时候,cpu系统总线检测cache的改变信号,然后产生无命中的信号,以中断方式传递给os,清洗脏数据,包括L1, L2两级缓存,都会有系统总线的cache监听信号。
如果读/写的数据长度和cache长度不符合,os还必须注意读/写数据的完整性,这个os也不能参与,只能适当的调整读出的位数为正确的数据长度。
cache查找速度和实现有关,如果是全路组方式,查找效率最高,但是冲突也会增加。
还有很多。。。。
[/quote:92ed7b3c8f]
CPU怎么得知他们之间的CACHE不一致呢?
如果允许不同CPU的内存子系统不一致的话,就是NUMA设计了,是大型机的设计思路(在这种平台上,线程才能爽起来). PC平台上似乎没有的.
低端UMA体系的设计思路是采用各种cache同步协议来避免不同CPU的内存子系统发生不一致. 比如Snoopy协议,就是让cpu内的CACHE管理检测总线上面进行的内存操作,在必要的时候产生总线请求硬件信号(参考CPU的BUSREQ管脚),刷新脏数据.
OS不参与所有这些操作.
|
| gvim 回复于:2005-01-11 00:35:52
|
是硬件管理的,但是要读取到正确的数据,需要os的配合,如果仅仅是cache的话,确实只有cpu的活动。在UNIX Systems for Modern Architectures 上面看到过这部分论证。(书不在手上,可能记忆比较模糊,如果还有什么不对的,也请指正)
NUMA我没有接触过,我只是了解MESI协议。
shit,我这两天犯糊涂,上面说的那个什么中断什么的,是虚拟内存的管理方式。
|
| 黄山松 回复于:2005-01-11 09:39:21
|
[quote:37fe2f9895="gvim"]是硬件管理的,但是要读取到正确的数据,需要os的配合,如果仅仅是cache的话,确实只有cpu的活动。在UNIX Systems for Modern Architectures 上面看到过这部分论证。(书不在手上,可能记忆比较模糊,如果还有什么不..........[/quote:37fe2f9895]
听说过MEI,请教MESI是什么东西?
|
| gvim 回复于:2005-01-11 10:09:42
|
[quote:6fd28fc395="黄山松"]
听说过MEI,请教MESI是什么东西?[/quote:6fd28fc395]
S 是Shared,共享态的意思。
|
| elssann 回复于:2005-01-11 17:58:22
|
[quote:d5ef922c42="JohnBull"]不能使用多线程,而应该使用多进程。
因为线程之间需要内存的共享,所以任何一个精神正常的人在设计操作系统的时候,都不会把同一个进程的多个线程分布到多个CPU中实现,否则线程间的数据共享会让总线效率剧烈下降?.........[/quote:d5ef922c42]
不会吧,谁这样说的, 在WINDOWS系统中,CPU的时间分配是以线程为单位的,而且现在LINUX下,2.6内核后的新的线程模型和新的内核调度器都可以让多个线程跑在不同的CPU上。
我觉得这个问题和KERNEL的内核调度器算法以及线程是内核线程模型还是用户线程模型等有关系。在LINUX2.6以前的内核上,确实一个进程里的线程只能在相同的一个CPU里执行。
|
| JohnBull 回复于:2005-01-11 19:09:17
|
[quote:f83fb7c8bc="elssann"]
不会吧,谁这样说的, 在WINDOWS系统中,CPU的时间分配是以线程为单位的,而且现在LINUX下,2.6内核后的新的线程模型和新的内核调度器都可以让多个线程跑在不同的CPU上。
我觉得这个问题和KERNEL的内核调度?..........[/quote:f83fb7c8bc]
不是不可以,而是不应该让从属于同一个进程的多个线程跑在不同的CPU上。
当初我们为什么设计线程?是为了让不同的执行上下文共享数据段.也就是说,当执行上下文之间需要大量数据段内容需要共享时,应当选择线程.
然而SMP的体系上的整个内存子系统是共享的,从属于同一个进程的多个线程跑在不同的CPU上势必造成内存子系统的访问趋于串行话,加速比会收到影响.
|
| 俊狼 回复于:2005-01-15 13:05:23
|
噢! 原来如此!
|
| cattiger 回复于:2005-01-15 19:24:33
|
我不明白多CPU是怎么分配资源的,一个进程,分配到多个CPU上,我觉得这个程序本身可以并行计算吧!不是随便拿一个程序来运行,就并行了!有一门课叫并行计算,我不知道是不是与多CPU有关,如果无关,为什么要并行,怎样才能实现并行呢?让大家见笑
|
| R.Ihskaka 回复于:2005-01-15 20:04:11
|
多处理器调度....这个其实首先应该看看你程序运行的平台.我们的程序是在OS之上建立的.因此MPS的调度要看OS的算法了.
如果将每个线程都放在不同的CPU中执行,就是OS给一个就绪队列,然后各个cpu都去那里取进程并执行,那么cpu的Cache效率就有可能很低下.而且有可能导致线程切换频繁(因为要同步的关系).
广泛使用的可能是成组分配方式.
而每个处理器一个进程,这个算是专用处理器分配方式,通常只有大型系统的OS才会使用到.一般的OS,特别是微机上,我想不会出现的.
To cattiger兄:
一个进程,应该只有再有线程的情况下才会分配到多个CPU中处理,还要考虑同步问题.一个孤独的进程,应该是不会同一时刻出现在多个CPU中跑的.要并行处理,应该也有特殊的要求,而不是任意一个程序都能这样的.当然这个是我自己的理解,没有参考什么资料.
|
| eagerly1 回复于:2005-01-16 11:18:52
|
[quote:3355f9630f="R.Ihskaka"]一个孤独的进程,应该是不会同一时刻出现在多个CPU中跑的......[/quote:3355f9630f]
进程可大可小,要看怎么样的进程了。
|
| sunlan 回复于:2005-01-16 16:34:03
|
[quote:ab1a832f8f="magicercn"]最好是能够充分利用系统的资源
希望有经验的各位高手指点。[/quote:ab1a832f8f]
这似乎并非纯代码能解决的问题。在CPU相同的前提下,系统开销主要用于进程的调度。同一进程在这个运行周期由CPU A执行,下一运行周期可能由CPU B执行,如果忽略CPU缓存的影响,多CPU和单CPU对该进程的执行时间应该是相同的。
效率最高的办法是用CPU绑定(模拟单进程操作系统,例如DOS),省去了调度的开销,效率绝对高!但这肯定会影响其它进程的运行。并且这种模式需要操作系统的支持。
|
| syxie 回复于:2005-01-16 17:38:20
|
[quote:346ee510ee="JohnBull"]
不是不可以,而是不应该让从属于同一个进程的多个线程跑在不同的CPU上。
当初我们为什么设计线程?是为了让不同的执行上下文共享数据段.也就是说,当执行上下文之间需要大量数据段内容需要共享时,应当选择线程.
然..........[/quote:346ee510ee]
说的有道理。
刚好遇到一个问题。在V880的机器上8CPU,Solaris8系统。
系统在运行的时候会有产生很多线程。当它运行的时候,8个CPU占用率接近80%,执行时间为38分钟;后来根据业务将线程分成3个进程(生成的总的线程数应该是一样的),CPU占用率降低为60%,执行时间在20分钟以内。
还在查为什么会这样呢。在看看还有没有优化的空间和方法。
不过,还写了一个代码,在2CPU上的执行效率,看使用不使用多线程的效率是一样的,就比较奇怪了。用的函数就是unix的基本函数pthread。
|
| syxie 回复于:2005-01-16 17:43:54
|
[quote:80ac7bfacc="JohnBull"]
CPU怎么得知他们之间的CACHE不一致呢?
如果允许不同CPU的内存子系统不一致的话,就是NUMA设计了,是大型机的设计思路(在这种平台上,线程才能爽起来). PC平台上似乎没有的.
低端UMA体系的设计思路是采用各种cache同?.........[/quote:80ac7bfacc]
不知道solaris操作系统,在使用多线程或者多进程的时候,无论cache或者什么的,有没有相关的操作系统配置参数,确保我的多CPU,多内存能够最大的使用,或者cache,或者编译选项。
|
| BetonArmEE 回复于:2005-01-18 14:42:05
|
学习中...
|
| lose 回复于:2005-01-19 11:23:10
|
对你的程序很感兴趣,能贴上来吗?
[quote:51163cea46="syxie"]
不知道solaris操作系统,在使用多线程或者多进程的时候,无论cache或者什么的,有没有相关的操作系统配置参数,确保我的多CPU,多内存能够最大的使用,或者cache,或者编译选项。[/quote:51163cea46]
|
| lose 回复于:2005-01-19 11:35:02
|
你的计算有问题。
10个进程运行9小时,也就是90个进程运行1小时,处理900个文件,
也就是一个进程运行1小时处理了10个文件,平均为6分钟处理一个文件。
比你单独运行sort 命令要快。
[quote:02ba450a7a="cnufo"]插个嘴请教一下
插个嘴请教一下
我要对900多个文件排序,每个文件200万行左右,总行数在1。8亿
开了十个进程排序竟然要9个小时
我直接用sort命令排序的
单个执行sort 一个文件才11分钟
为什么并行后平均下来一个进程一个小时只排序一个文件呢?[/quote:02ba450a7a]
|
| lose 回复于:2005-01-19 14:32:04
|
可以使用vmstat来查看你的程序再干什么,是在cpu 上运行还是在I/O等待,还是在做page in/page out。这些和你使用的机器以及操作系统有很大关系。如果是solaris的,我还比较熟悉。也许可以帮你分析一下。
[quote:79c1b93508="magicercn"][/quote:79c1b93508]
|
| lose 回复于:2005-01-19 15:33:09
|
syxie,可否吧你的程序发邮件给我。想看看你的程序,因为最近对并行计算比较感兴趣。
和另外一个同事谈了一下,感觉你的情况是反常的。应该是一个进程派生多个子线程性能更好一些。
[quote:abe84046eb="syxie"]
JohnBull 写到:
不是不可以,而是不应该让从属于同一个进程的多个线程跑在不同的CPU上。
当初我们为什么设计线程?是为了让不同的执行上下文共享数据段.也就是说,当执行上下文之间需要大量数据段内容需要共享时,应当选择线程.
然..........
说的有道理。
刚好遇到一个问题。在V880的机器上8CPU,Solaris8系统。
系统在运行的时候会有产生很多线程。当它运行的时候,8个CPU占用率接近80%,执行时间为38分钟;后来根据业务将线程分成3个进程(生成的总的线程数应该是一样的),CPU占用率降低为60%,执行时间在20分钟以内。
还在查为什么会这样呢。在看看还有没有优化的空间和方法。
不过,还写了一个代码,在2CPU上的执行效率,看使用不使用多线程的效率是一样的,就比较奇怪了。用的函数就是unix的基本函数pthread。
....[/quote:abe84046eb]
|
| lose 回复于:2005-01-19 15:38:46
|
你的这些话是有问题的。
solaris 的内核就是多线程的。
线程间的数据共享是它的优点,是提高性能的关键。
[quote:abb6a1606e="JohnBull"]不能使用多线程,而应该使用多进程。
因为线程之间需要内存的共享,所以任何一个精神正常的人在设计操作系统的时候,都不会把同一个进程的多个线程分布到多个CPU中实现,否则线程间的数据共享会让总线效率剧烈下降?.........[/quote:abb6a1606e]
|
| mingyanguo 回复于:2005-05-14 23:52:22
|
[quote:07bab00e21="JohnBull"]
不是不可以,而是不应该让从属于同一个进程的多个线程跑在不同的CPU上。
当初我们为什么设计线程?是为了让不同的执行上下文共享数据段.也就是说,当执行上下文之间需要大量数据段内容需要共享时,应当选择线程.
然..........[/quote:07bab00e21]
i can't agree more.
"不应该让从属于同一个进程的多个线程跑在不同的CPU上"
see FreeBSD's KSE or SA
or Solaris thread
|