go的go while true怎么不耗费cpu

如何将所有的进程运行在一个指定的CPU上 - CSDN博客
如何将所有的进程运行在一个指定的CPU上
转载:http://blog.csdn.net/sunvince/article/details/6533016
这是CU上的一个问题...
在SMP上,想把所有的&态进程运行在一个CPU上,腾出其它CPU干其它事。Linux能通过简单的配置实现吗?而不是去修改内核代码。
Linux 内核 API 提供了一些方法,让用户可以修改位掩码或查看当前的位掩码:
sched_set_affinity() (用来修改位掩码)
sched_get_affinity() (用来查看当前的位掩码)
不改内核的话,直接用 taskset&&命令就可以啦,兄弟。
不过我喜欢直接在内核里面修改 sched_set_affinity,这样用户空间就省事了。
下面转载... taskset使用方法&
from: http://www.blogkid.net/archives/2670.html
我的&十分繁忙,在跑一些密集操作数据库的Rake任务时尤其如此。但我观察发现,Linode服务器的4核CPU,只有第1个核心(CPU#0)非常忙,其他都处于idle状态。
不了解Linux是如何调度的,但目前显然有优化的余地。除了处理正常任务,CPU#0还需要处理每秒&网卡中断。因此,若能将CPU#0分担的任务摊派到其他CPU核心上,可以预见,系统的处理能力将有更大的提升。
SMP&(Symmetrical Multi-Processing):指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。 [&]
CPU affinity&:中文唤作“CPU亲和力”,是指在CMP架构下,能够将一个或多个进程绑定到一个或多个处理器上运行。[&]
一、在Linux上修改进程的“CPU亲和力”
在Linux上,可以通过&命令进行修改。以Ubuntu为例,运行如下命令可以安装taskset&工具。
# apt-get install schedutils
对运行中的进程,文档上说可以用下面的命令,把CPU#1 #2 #3分配给PID为2345的进程:
# taskset -cp 1,2,3 2345
但我尝试没奏效&,于是我关掉了,并用taskset将它启动:
# taskset -c 1,2,3 /etc/init.d/mysql start
对于其他进程,也可如此处理(nginx除外,详见下文)。之后用top查看CPU的使用情况,原来空闲的#1 #2 #3,已经在辛勤工作了。
二、配置nginx绑定CPU
刚才说nginx除外,是因为nginx提供了更精确的控制。
在conf/nginx.conf&中,有如下一行:
worker_processes& 1;
这是用来配置nginx启动几个工作进程的,默认为1。而nginx还支持一个名为worker_cpu_affinity的配置项,也就是说,nginx可以为每个工作进程绑定CPU&。我做了如下配置:
worker_processes& 3;
worker_cpu_affinity 00;
这里00是掩码,分别代表第2、3、4颗cpu核心。
重启nginx后,3个工作进程就可以各自用各自的CPU了。
三、刨根问底
如果自己写代码,要把进程绑定到CPU,该怎么做?可以用函数。在Linux上,这会触发一次&。如果父进程设置了affinity,之后其创建的子进程是否会有同样的属性?我发现子进程确实继承了父进程的affinity属性。
四、Windows?
在Windows上修改“CPU亲和力”,可以通过任务管理器搞定。
* 个人感觉,Windows系统中翻译的“处理器关系”比“CPU亲和力”容易理解点儿
—————–
进行了这样的修改后,即使系统负载达到3以上,不带缓存打开blogkid.net首页(有40多次查询)依然顺畅;以前一旦负载超过了1.5,响应就很慢了。效果很明显。
另外还有一篇文章:详细的用程序例子分析了CPU affinity (亲和力)
from:http://fuzhong1983./blog/static//
分类:&&949人阅读&&&
简单地说,CPU 亲和性(affinity)&就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性。Linux 内核进程调度器天生就具有被称为&软 CPU 亲和性(affinity)&的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。
2.6 版本的 Linux 内核还包含了一种机制,它让开发人员可以编程实现&硬 CPU 亲和性(affinity)。这意味着应用程序可以显式地指定进程在哪个(或哪些)处理器上运行。
什么是 Linux 内核硬亲和性(affinity)?
在 Linux 内核中,所有的进程都有一个相关的数据结构,称为&task_struct。这个结构非常重要,原因有很多;其中与 亲和性(affinity)相关度最高的是&cpus_allowed&位掩码。这个位掩码由&n&位组成,与系统中的&n&个逻辑处理器一一对应。 具有 4 个物理 CPU 的系统可以有 4 位。如果这些 CPU 都启用了超线程,那么这个系统就有一个 8 位的位掩码。
如果为给定的进程设置了给定的位,那么这个进程就可以在相关的 CPU 上运行。因此,如果一个进程可以在任何 CPU 上运行,并且能够根据需要在处理器之间进行迁移,那么位掩码就全是 1。实际上,这就是 Linux 中进程的缺省状态。
Linux 内核 API 提供了一些方法,让用户可以修改位掩码或查看当前的位掩码:
sched_set_affinity()&(用来修改位掩码)sched_get_affinity()&(用来查看当前的位掩码)
注意,cpu_affinity&会被传递给子线程,因此应该适当地调用&sched_set_affinity。
为什么应该使用硬亲和性(affinity)?
通常 Linux 内核都可以很好地对进程进行调度,在应该运行的地方运行进程(这就是说,在可用的处理器上运行并获得很好的整体性能)。内核包含了一些用来检测 CPU 之间任务负载迁移的算法,可以启用进程迁移来降低繁忙的处理器的压力。
一般情况下,在应用程序中只需使用缺省的调度器行为。然而,您可能会希望修改这些缺省行为以实现性能的优化。让我们来看一下使用硬亲和性(affinity) 的 3 个原因。
原因 1. 有大量计算要做
基于大量计算的情形通常出现在科学和理论计算中,但是通用领域的计算也可能出现这种情况。一个常见的标志是您发现自己的应用程序要在多处理器的机器上花费大量的计算时间。
原因 2. 您在测试复杂的应用程序
测试复杂软件是我们对内核的亲和性(affinity)技术感兴趣的另外一个原因。考虑一个需要进行线性可伸缩性测试的应用程序。有些产品声明可以在&使用更多硬件&时执行得更好。
我们不用购买多台机器(为每种处理器配置都购买一台机器),而是可以:
购买一台多处理器的机器不断增加分配的处理器测量每秒的事务数评估结果的可伸缩性
如果应用程序随着 CPU 的增加可以线性地伸缩,那么每秒事务数和 CPU 个数之间应该会是线性的关系(例如斜线图 —— 请参阅下一节的内容)。这样建模可以确定应用程序是否可以有效地使用底层硬件。
Amdahl 法则说明这种加速比在现实中可能并不会发生,但是可以非常接近于该值。对于通常情况来说,我们可以推论出每个程序都有一些串行的组件。随着问题集不断变大,串行组件最终会在优化解决方案时间方面达到一个上限。
Amdahl 法则在希望保持高 CPU 缓存命中率时尤其重要。如果一个给定的进程迁移到其他地方去了,那么它就失去了利用 CPU 缓存的优势。实际上,如果正在使用的 CPU 需要为自己缓存一些特殊的数据,那么所有其他 CPU 都会使这些数据在自己的缓存中失效。
因此,如果有多个线程都需要相同的数据,那么将这些线程绑定到一个特定的 CPU 上是非常有意义的,这样就确保它们可以访问相同的缓存数据(或者至少可以提高缓存的命中率)。否则,这些线程可能会在不同的 CPU 上执行,这样会频繁地使其他缓存项失效。
原因 3. 您正在运行时间敏感的、决定性的进程
我们对 CPU 亲和性(affinity)感兴趣的最后一个原因是实时(对时间敏感的)进程。例如,您可能会希望使用硬亲和性(affinity)来指定一个 8 路主机上的某个处理器,而同时允许其他 7 个处理器处理所有普通的系统调度。这种做法确保长时间运行、对时间敏感的应用程序可以得到运行,同时可以允许其他应用程序独占其余的计算资源。
下面的样例应用程序显示了这是如何工作的。
如何利用硬亲和性(affinity)
现在让我们来设计一个程序,它可以让 Linux 系统非常繁忙。可以使用前面介绍的系统调用和另外一些用来说明系统中有多少处理器的 API 来构建这个应用程序。实际上,我们的目标是编写这样一个程序:它可以让系统中的每个处理器都繁忙几秒钟。
清单 1. 让处理器繁忙
/* This method will create threads, then bind each to its own cpu. */
bool do_cpu_stress(int numthreads)
int ret = TRUE;
int created_thread = 0;
/* We need a thread for each cpu we have... */
while ( created_thread & numthreads - 1 )
int mypid = fork();
if (mypid == 0) /* Child process */
printf(&\tCreating Child Thread: #%i\n&, created_thread);
else /* Only parent executes this */
/* Continue looping until we spawned enough threads! */ ;
created_thread++;
/* NOTE: All threads execute code from here down! */
正如您可以看到的一样,这段代码只是通过 fork 调用简单地创建一组线程。每个线程都执行这个方法中后面的代码。现在我们让每个线程都将亲和性(affinity)设置为自己的 CPU。
清单 2. 为每个线程设置 CPU 亲和性(affinity)
/* CPU_ZERO initializes all the bits in the mask to zero. */
CPU_ZERO( &mask );
/* CPU_SET sets only the bit corresponding to cpu. */
CPU_SET( created_thread, &mask );
/* sched_setaffinity returns 0 in success */
if( sched_setaffinity( 0, sizeof(mask), &mask ) == -1 )
printf(&WARNING: Could not set CPU Affinity, continuing...\n&);
如果程序可以执行到这儿,那么我们的线程就已经设置了自己的亲和性(affinity)。调用&sched_setaffinity&会设置由&pid&所引用的进程的 CPU 亲和性(affinity)掩码。如果&pid&为 0,那么就使用当前进程。
亲和性(affinity)掩码是使用在&mask&中存储的位掩码来表示的。最低位对应于系统中的第一个逻辑处理器,而最高位则对应于系统中最后一个逻辑处理器。
每个设置的位都对应一个可以合法调度的 CPU,而未设置的位则对应一个不可调度的 CPU。换而言之,进程都被绑定了,只能在那些对应位被设置了的处理器上运行。通常,掩码中的所有位都被置位了。这些线程的亲和性(affinity)都会传递给从它们派生的子进程中。
注意不应该直接修改位掩码。应该使用下面的宏。虽然在我们的例子中并没有全部使用这些宏,但是在本文中还是详细列出了这些宏,您在自己的程序中可能需要这些宏。
清单 3. 间接修改位掩码的宏
void CPU_ZERO (cpu_set_t *set)
这个宏对 CPU 集 set 进行初始化,将其设置为空集。
void CPU_SET (int cpu, cpu_set_t *set)
这个宏将 cpu 加入 CPU 集 set 中。
void CPU_CLR (int cpu, cpu_set_t *set)
这个宏将 cpu 从 CPU 集 set 中删除。
int CPU_ISSET (int cpu, const cpu_set_t *set)
如果 cpu 是 CPU 集 set 的一员,这个宏就返回一个非零值(true),否则就返回零(false)。
对于本文来说,样例代码会继续让每个线程都执行某些计算量较大的操作。
清单 4. 每个线程都执行一个计算敏感的操作
/* Now we have a single thread bound to each cpu on the system */
int computation_res = do_cpu_expensive_op(41);
sched_getaffinity(0, sizeof(mycpuid), &mycpuid);
if ( check_cpu_expensive_op(computation_res) )
printf(&SUCCESS: Thread completed, and PASSED integrity check!\n&,
ret = TRUE;
printf(&FAILURE: Thread failed integrity check!\n&,
ret = FALSE;
现在您已经了解了在 Linux 2.6 版本的内核中设置 CPU 亲和性(affinity)的基本知识。接下来,我们使用一个&main&程序来封装这些方法,它使用一个用户指定的参数来说明要让多少个 CPU 繁忙。我们可以使用另外一个方法来确定系统中有多少个处理器:
int NUM_PROCS = sysconf(_SC_NPROCESSORS_CONF);
这个方法让程序能够自己确定要让多少个处理器保持繁忙,例如缺省让所有的处理器都处于繁忙状态,并允许用户指定系统中实际处理器范围的一个子集。
运行样例程序
当运行前面介绍的样例程序时,可以使用很多工具来查看 CPU 是否是繁忙的。如果只是简单地进行测试,可以使用 Linux 命令top。在运行&top&命令时按下 “1” 键,可以看到每个 CPU 执行进程所占用的百分比。
这个样例程序虽然非常简单,但是它却展示了使用 Linux 内核中实现的硬亲和性(affinity)的基本知识。(任何使用这段代码的应用程序都无疑会做一些更有意义的事情。)了解了 CPU 亲和性(affinity)内核 API 的基本知识,您就可以从复杂的应用程序中榨取出最后一点儿性能了。
本文已收录于以下专栏:
相关文章推荐
Nginx 配置文件 nginx.conf
首先需要找到 Nginx 的配置文件 nginx.conf 才能进行下面的操作,在LNMP一键安装包默认配置下,nginx.conf
转载:http://blog.csdn.net/sunvince/article/details/6533016
这是CU上的一个问题...
from: http://b...
这是CU上的一个问题... from:http://bbs.chinaunix.net/viewthread.php?tid=0; 在SMP上,想把所有的用户态进程运行在一个CPU上,腾出...
google一圈,能够实现的方式有两种:第一种:linux的shell命令行方式,命令名字为taskset。第二种就是代码实现级别的了,pthread_setaffinity_np和sched_set...
进程与指定cpu绑定:SetProcessAffinityMask(GetCurrentProcess(), dwMask);
线程与指定cpu绑定:SetThreadAffinit...
文章转自/liuhao/archive//2558069.html
如果你觉得比内核的进程调度器更了解你的进程,不想过多的占用CPU0,更高的缓存命中,那么可以设置进程运行在某个或某些CPU上。
   redis是单进程模型,为了充分利用多核服务器性能,可以指定不同...
coolshell最新的文章《性能调优攻略》在“多核CPU调优”章节,提到“我们不能任由操作系统负载均衡,因为我们自己更了解自己的程序,所以,我们可以手动地为其分配CPU核,而不会过多地占用CPU0,...
原文链接:http://blog.csdn.net/harbinzju/article/details/7023630
进程与指定cpu绑定:SetProcessAffinity...
/liuhao/archive//2558069.html 
如何指定进程运行的CPU
他的最新文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)1 --毛利统计
2 -- zwf 3 &ALTER
PROCEDURE [dbo].[GrossQueryByType] 4 ( 5
@store_idList varchar(500), 6
@bdate char(10), 7
@edate char(10), 8
@goodstype varchar(30) 9 )10 AS11
--生成临时表12
CREATE TABLE # (13
[store_id] varchar(15),14
[goods_id] [varchar] (6) ,15
[goods_name] varchar(50),16
[sQty] [decimal](10, 2) NULL ,17
[sRamt] [decimal](10, 2) NULL ,18
[eQty] [decimal](10, 2) NULL ,19
[eRamt] [decimal](10, 2) NULL ,20
[buyQty] [decimal](10, 2) NULL ,21
[buyRamt] [decimal](10, 2) NULL ,22
[saleQty] [decimal](10, 2) NULL ,23
[saleRamt] [decimal](10, 2) NULL ,24
[inQty] [decimal](18, 0) NULL ,25
[inRamt] [decimal](10, 2) NULL ,26
[outQty] [decimal](10, 2) NULL ,27
[outRamt] [decimal](10, 2) NULL ,28
[gross] [decimal](10, 2) NULL ,29
[grossRate] [decimal](10, 2) NULL ,30
[saleCost] [decimal](10,2) NULL,31
[packnum1] int32
INDEX [IX_#] ON #([store_id], [goods_id])35
declare @sqlStr varchar(5000)36
declare @store_id varchar(15)37
CREATE TABLE #A(STORE_ID VARCHAR(15),store_name varchar(50))38
store_id,store_name
@i=count(1)
@store_id= store_id
--分割超市编号45
--取所有商品46
insert into # select @store_id,goods_id,goods_name,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,packnum1 from t_goods47
--生成期初库存48
update # set sqty=a.sqty,sRamt=a.sRamt49
from t_goods_jxc_ a50
where convert(char(10),a.sdate,121)=@bdate and a.store_id=@store_id51
and #.goods_id=a.goods_id and #.store_id=@store_id52
--生成购进和销售数据及库存调拨数据及毛利54
update # set buyqty=t.buyqty_,buyRamt=t.buyRamt_,saleqty=t.saleQty_,saleRamt=t.saleRamt_,inqty=t.inQty_,inRamt=t.inRamt_,outqty=t.outQty_,outRamt=t.outRamt_,gross=t.gross_--,eqty=t.eqty_,eramt=t.eramt_ 55
from #,(56
select goods_id,sum(buyQty) buyQty_,sum(buyRamt)/1.17 buyRamt_,sum(saleQty) saleQty_,sum(saleRamt)/1.17 saleRamt_,sum(inQty) inQty_,sum(inRamt) inRamt_,sum(outQty) outQty_,sum(outRamt) outRamt_,sum(gross) gross_,sum(eqty) eqty_,sum(eramt) eramt_ 57
from T_Goods_Jxc_58
where convert(char(10),sdate,121)&=@edate and convert(char(10),sdate,121)&=@bdate and store_id=@store_id59
group by goods_id60
where #.goods_id=t.goods_id and #.store_id=@store_id62
update # set eqty=a.eqty,eRamt=a.eRamt65
from t_goods_jxc_ a66
where convert(char(10),a.sdate,121)=@edate and a.store_id=@store_id67
and #.goods_id=a.goods_id and #.store_id=@store_id68
--清除从来有发生过进销存业务的商品70
from # where sqty=0 and buyqty=0 and saleqty=0 and eqty=071
--fetch next from @shopcursor into @store_id 72
update # set eramt= 0 where eqty=078
update # set gross= saleRamt - sramt - inramt - buyramt + outramt + eramt
update # set saleCost=sramt+buyramt+inramt-outramt-eramt
--成本80 81
if( @goodstype is null)82
select goods_id,goods_name,sum(sQty/packnum1) sQty,sum(sRamt) sRamt,sum(eQty/packnum1) eqty,sum(eRamt) eRamt,--(sum(sramt)+sum(buyramt))/(sum(sqty)+sum(buyqty))*sum(eqty) eramt, --83
sum(buyQty/packnum1) buyQty ,sum(buyRamt) buyRamt,sum(saleQty/packnum1) saleQty,sum(saleRamt) saleRamt,84
sum(inQty/packnum1) inQty ,sum(inRamt) inRamt ,sum(outQty/packnum1) outQty ,sum(outRamt) outRamt,sum(gross) gross,(sum(gross)/1.17)/(case (sum(saleRamt)) when 0 then 1 else sum(saleRamt)/1.17 end)*100 grossrate,sum(saleCost) salecost85
group by goods_id,goods_name
else --if(not @goodstype is null)88
select goods_id,goods_name,sum(sQty/packnum1) sQty,sum(sRamt) sRamt,sum(eQty/packnum1) eqty,sum(eRamt) eRamt,--(sum(sramt)+sum(buyramt))/(sum(sqty)+sum(buyqty))*sum(eqty) eramt, --89
sum(buyQty/packnum1) buyQty ,sum(buyRamt) buyRamt,sum(saleQty/packnum1) saleQty,sum(saleRamt) saleRamt,90
sum(inQty/packnum1) inQty ,sum(inRamt) inRamt ,sum(outQty/packnum1) outQty ,sum(outRamt) outRamt,sum(gross) gross,(sum(gross)/1.17)/(case (sum(saleRamt)) when 0 then 1 else sum(saleRamt)/1.17 end)*100 grossrate,sum(saleCost) salecost91
goods_id in (select a.goods_id from T_Goods a,T_Sys_Dictionary b where a.brand = b.code and b.parent_sid=@goodstype)
group by goods_id,goods_name94 GO
提问于: 11:12
分享您的问题
其他回答(1)
给临时表添加索引,看看能不能不用游标,改写你的存储过程。
园豆:1050
园豆:1050
去掉临时表,用cte&,with 语句;临时表的效率较低,cte应该好一些的
不过你这么多数据,每次都处理,运算量本来也就很大,我想还要想办法减少调用次数(缓存,定时作业之类的)
园豆:3395
园豆:3395
园豆:3395
&&&您需要以后才能回答,未注册用户请先。

我要回帖

更多关于 java while true cpu 的文章

 

随机推荐