首页 > 编程技术 > php

多核编程中的负载平衡难题

发布时间:2016-11-25 16:32

多核CPU中,要很好地发挥出多个CPU的性能的话,必须保证分配到各个CPU上的任务有一个很好的负载平衡。否则一些CPU在运行,另外一些CPU处于空闲,无法发挥出多核CPU的优势来。


  要实现一个好的负载平衡通常有两种方案,一种是静态负载平衡,另外一种是动态负载平衡。


  1、静态负载平衡


  静态负载平衡中,需要人工将程序分割成多个可并行执行的部分,并且要保证分割成的各个部分能够均衡地分布到各个CPU上运行,也就是说工作量要在多个任务间进行均匀的分配,使得达到高的加速系数。


  静态负载平衡问题从数学上来说是一个NP完全性问题,Richard M. Karp, Jeffrey D. Ullman, Christos H. Papadimitriou, M. Garey, D. Johnson等人相继在1972年到1983年间证实了静态负载问题在几种不同约束条件下的NP完全性。


  虽然NP完全性问题在数学上是难题,但是这并不是标题中所说的难题,因为NP完全性问题一般都可以找到很有效的近似算法来解决。


  2、动态负载平衡


  动态负载平衡是在程序的运行过程中来进行任务的分配达到负载平衡的目的。实际情况中存在许多不能由静态负载平衡解决的问题,比如一个大的循环中,循环的次数是由外部输入的,事先并不知道循环的次数,此时采用静态负载平衡划分策略就很难实现负载平衡。


  动态负载平衡中对任务的调度一般是由系统来实现的,程序员通常只能选择动态平衡的调度策略,不能修改调度策略,由于实际任务中存在很多的不确定因素,调度算法无法做得很优,因此动态负载平衡有时可能达不到既定的负载平衡要求。


  3、负载平衡的难题在那里?


  负载平衡的难题并不在于负载平衡的程度要达到多少,因为即使在各个CPU上分配的任务执行时间存在一些差距,但是随着CPU核数的增多总能让总的执行时间下降,从而使加速系数随CPU核数的增加而增加。


  负载平衡的困难之处在于程序中的可并行执行块很多要靠程序员来划分,当然CPU核数较少时,比如双核或4核,这种划分并不是很困难。但随着核数的增加,划分的粒度将变得越来越细,到了16核以上时,估计程序员要为如何划分任务而抓狂。比如一段顺序执行的代码,放到128核的CPU上运行,要手工划分成128个任务,其划分的难度可想而知。


  负载划分的误差会随着CPU核数的增加而放大,比如一个需要16个时间单位的程序分到4个任务上执行,平均每个任务上的负载执行时间为4个时间单位,划分误差为1个时间单位的话,那么加速系数变成 16/(4 1)=3.2,是理想情况下加速系数 4的80%。但是假如放到一个16核CPU上运行的话,假如某个任务的划分误差假如为0.5个时间单位的话,那么加速系数变成16/(1 0.5) = 10.67,只有理想的加速系数16的66.7%,假如核数再增加的话,由于误差的放大,加速系数相比于理想加速系数的比例还会下降。


  负载划分的难题还体现在CPU和软件的升级上,比如在4核CPU上的负载划分是均衡的,但到了8核、16核上,负载也许又变得不均衡了。软件升级也一样,当软件增加功能后,负载平衡又会遭到破坏,又需要重新划分负载使其达到平衡,这样一来软件设计的难度和麻烦大大增加了。


  假如使用了锁的话,一些看起来是均衡的负载也可能会由于锁竞争变得不平衡起来。


  4、负载平衡的应对策略


  对于运算量较小的软件,即使放到单核CPU上运行速度也很快,负载平衡做得差一些并没有太大影响,实际中负载平衡要考虑的是大运算量和规模很大的软件,这些软件需要在多核上进行负载平衡才能较好地利用多核来提高性能。


  对于大规模的软件,负载平衡方面采取的应对策略是发展划分并行块的宏观划分方法,从整个软件系统层面来进行划分,而不是象传统的针对某些局部的程序和算法来进行并行分解,因为局部的程序通常都很难分解成几十个以上的任务来运行。


  另外一个应对策略是在工具层面的,也就是编译工具能够协助人工进行并行块的分解,并找出良好的分解方案来,这方面Intel已经作出了一些努力,但是还需要更多的努力让工具的功能更强大一些才能应对核数较多时的情况。

禁止屏蔽类

  1.禁止右键

<body oncontextmenu=return(false)>

  2.禁止选择

<body onselectstart="return false">

  3.禁止粘贴

<body onpaste="return false">
 
  4.禁止直接访问 [必须框架内才行]

<script>
if (top == self)top.location.href = "page.htm";
</script>

  5.禁止frame引用

<script>
if (top != self)top.location.href = "page.htm";
</script>

  6.禁止功能键Shift,Alt,Ctrl

<script>function key(){
if(event.shiftKey) alert("Shift不答应使用!");} document.onkeydown=key; </script>

  数据取得类

  1.取得分辨率

<script>document.write("宽为" screen.Width "高为" screen.Height)</script>

  2.取得地址栏

<script>document.write(self.location)</script>

  3.取得地址栏后参数

<SCRIPT>var add = top.location;
add = add.toString();
document.write (add.substring(add.indexOf("?") 1,add.length));
</SCRIPT>

你一定会笑我“下载文件”如此简单都值得说?当然并不是想你想象的那么简单。例如你希望客户要填完一份表格,才可以下载某一文件,你第一个想法一定是用 “Redirect”的方法,先检查表格是否已经填写完毕和完整,然后就将网址指到该文件,这样客户才能下载,例如笔者编写的以下代码:

<?

// 检查 FORM 是否全部填写完毕...

if ($form_completed) {

Header("Location: http://www.etoow.com/download/info_check.exe");

exit;

}

?>

或者是以下的情况:

“ <a href="http://www.etoow.com/users/download.php?id=124524">开始下载文件</a> ”

这里利用了ID方式接收要下载文件的编号,然后用“Redirect”的方式连接到实际的网址。

假如你想做一个关于“网上购物”的电子商务网站,考虑安全问题,你不想用户直接复制网址下载该文件,笔者建议你使用PHP直接读取该实际文件然后下载的方法去做。程序如下:

<?

$file_name = "info_check.exe";

$file_dir = "/public/www/download/";

if (!file_exists($file_dir . $file_name)) { //检查文件是否存在

echo "文件找不到";

exit;

} else {

$file = fopen($file_dir . $file_name,"r"); // 打开文件

// 输入文件标签

Header("Content-type: application/octet-stream");

Header("Accept-Ranges: bytes");

 支持WAP功能的移动电话越来越多了。因此,你也应该考虑一下建立自己的WML网站了,本文要介绍的是如何建立PHP/WML页面的站点,使用MySQL数据库,可动态更新站点的内容,具体例子是某个学院的教授授课时间和测验时间表。一点也不复杂哦 :-)
  在开始之前,你应该预备好以下东东:

  1.你已经正确安装好PHP和MySQL,并且有使用两者编程的经验。
  2.你有SQL的相关知识
  3.你运行的是Apache并且可写.haccess文件;或者你运行IIS并且你可以增加映射(或者你可以让系统治理员帮你的忙);
  4.你有WML的相关知识;

  好了,第一步首先让你的服务器知道使用PHP来处理WML文件,以下介绍如何做到这一点。

设置服务器

   假如你使用的是Apache,你必须在你的目录中找到一个.htaccess文件。然后,加入以下行:

    AddType application/x-httpd-php3 .wml

  假如你找不到该文件,可以加入一个,并且加入以上行,放在你的目录中。

  假如你使用的是IIS,你必须做一些改动,与安装PHP时差不多:看一下.php和.php3扩展名的映射,并且为.wml加入同样的映射处理。

  通常你会发现PHP被映射到:

   C:phpphp4isapi.dll

  或者

   C:phpphp.exe

预备工作

  假如你使用的是微软的操作系统,你可以安装NOKIA的开发工具包。它可以检查你的语法,并且让你通过一个类似电话的界面来预览WML页面,该工具包还带有关于WML和WML脚本的参考文档。假如你的电话没有WAP支持,或者你不能使用一个WAP网关,这可以帮上大忙哦。

  要下载这个工具,你首先必须以一个WAP开发者的身份在这个网站登记(http://www.forum.nokia.com/main/0,6668,1_1_4,00.html),要记住的是你需要Java2 Runtime Enviroment的支持(Java2运行环境的支持)。你可以使用任何的文本编辑器来写页面。

  在写任何PHP/WML代码前,你需要建好MySQL的表格。

  该数据库由4个表够成。

  1.professors表包括教授的相关数据;
  2.subjucts表包括主题的相关数据;
  3.exams表包括测验的相关数据;
  4.teach表包括教授和他们所授科目的关系信息

  在连接MySQL时,可通过以下的代码建立表格
CREATE TABLE professors (
Id int(11) DEFAULT '0' NOT NULL auto_increment,
Surname varchar(24) NOT NULL,
Name varchar(24) NOT NULL,
Email varchar(48) DEFAULT 'Not avaliable',
Cod_course varchar(16) DEFAULT 'Not avaliable',
Consulting_hour varchar(128) DEFAULT 'Not avaliable',
Consulting_place varchar(128) DEFAULT 'Not avaliable',
PRIMARY KEY (Id)
);

  这些语句建立了professors的表结构。ID为每个教授分配了一个唯一的识别号,而且是表的主键。其它字段,Surname, Name, Email用来表示每个教授的姓、名字和e-mail地址。Cod_course为唯一识别每个科目值。最后Consulting_hour和Consulting_place表示授课时间和授课的地点。

CREATE TABLE subjects (
Subject varchar(96) NOT NULL,
Cod_Subject varchar(24) NOT NULL,
Cod_number varchar(12) NOT NULL,
PRIMARY KEY (Cod_subject )
);

  Subject是科目的名字,Cod_subject是学院采用的代表每个科目的名字,它的值是唯一的,并且是这个表的主键。Cod_number是一个数字的字段,相同科目的不同课程都属于一个组,这个数字就是组的识别号。

CREATE TABLE exams (
Cod_Subject varchar(24) NOT NULL,

<?
/**
* 转换为UNIX时间戳
*/
function gettime($d) {
if(is_numeric($d))
return $d;
else {
if(! is_string($d)) return 0;
if(ereg(":",$d)) {
$buf = split(" ",$d);
$year = split("[-/]",$buf[0]);
$hour = split(":",$buf[1]);
if(eregi("pm",$buf[2]))
$hour[0] = 12;
return mktime($hour[0],$hour[1],$hour[2],$year[1],$year[2],$year[0]);
}else {
$year = split("[-/]",$d);
return mktime(0,0,0,$year[1],$year[2],$year[0]);
}
}
}

/**
*
* DateAdd(interval,number,date)
* 返回已添加指定时间间隔的日期。
* Inetrval为表示要添加的时间间隔字符串表达式,例如分或天
* number为表示要添加的时间间隔的个数的数值表达式
* Date表示日期
*
* Interval(时间间隔字符串表达式)可以是以下任意值:
* yyyy year年
* q Quarter季度
* m Month月
* y Day of year一年的数
* d Day天
* w Weekday一周的天数
* ww Week of year周
* h Hour小时
* n Minute分
* s Second秒
* w、y和d的作用是完全一样的,即在目前的日期上加一天,q加3个月,ww加7天。
*/
function DateAdd($interval, $number, $date) {
$date = gettime($date);
$date_time_array = getdate($date);
$hours = $date_time_array["hours"];
$minutes = $date_time_array["minutes"];
$seconds = $date_time_array["seconds"];
$month = $date_time_array["mon"];

标签:[!--infotagslink--]

您可能感兴趣的文章: