TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.0 KiB
178 lines
4.0 KiB
<?php
|
|
|
|
/*
|
|
The Computer Language Benchmarks Game
|
|
https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
|
|
|
|
contributed by Nikita Popov
|
|
*/
|
|
|
|
|
|
function A($i, $j)
|
|
{
|
|
return 1.0 / (((($i + $j) * ($i + $j + 1)) >> 1) + $i + 1);
|
|
}
|
|
|
|
function Av($n, $v, $start, $end)
|
|
{
|
|
global $_tpl;
|
|
$Av = $_tpl;
|
|
for ($i = $start; $i < $end; ++$i) {
|
|
$sum = 0.0;
|
|
foreach ($v as $j => $v_j) {
|
|
$sum += A($i, $j) * $v_j;
|
|
}
|
|
$Av[$i] = $sum;
|
|
}
|
|
return $Av;
|
|
}
|
|
|
|
function Atv($n, $v, $start, $end)
|
|
{
|
|
global $_tpl;
|
|
$Atv = $_tpl;
|
|
for ($i = $start; $i < $end; ++$i) {
|
|
$sum = 0.0;
|
|
foreach ($v as $j => $v_j) {
|
|
$sum += A($j, $i) * $v_j;
|
|
}
|
|
$Atv[$i] = $sum;
|
|
}
|
|
return $Atv;
|
|
}
|
|
|
|
function AtAv($n, $v, $start, $end, $sync)
|
|
{
|
|
|
|
$tmp = Av($n, $v, $start, $end);
|
|
if ($sync) $tmp = sync($tmp);
|
|
|
|
$tmp = Atv($n, $tmp, $start, $end);
|
|
if ($sync) $tmp = sync($tmp);
|
|
|
|
return $tmp;
|
|
}
|
|
|
|
function sync($tmp)
|
|
{
|
|
global $parent, $chunk_data_size, $total_data_size, $pipe, $pipes;
|
|
|
|
if (!$parent) {
|
|
$data = call_user_func_array('pack', array_merge(['d*'], $tmp));
|
|
safe_write($pipe, $data);
|
|
return array_values(unpack('d*', safe_read($pipe, $total_data_size)));
|
|
} else {
|
|
$tmps = array();
|
|
foreach ($pipes as $_pipe) {
|
|
$tmps[] = unpack('d*', safe_read($_pipe, $chunk_data_size));
|
|
}
|
|
$tmps[] = $tmp;
|
|
$tmp = call_user_func_array('array_merge', $tmps);
|
|
|
|
$data = call_user_func_array('pack', array_merge(['d*'], $tmp));
|
|
foreach ($pipes as $_pipe) {
|
|
safe_write($_pipe, $data);
|
|
}
|
|
return $tmp;
|
|
}
|
|
}
|
|
|
|
function safe_write($fd, $data)
|
|
{
|
|
$len = strlen($data);
|
|
do {
|
|
$w = fwrite($fd, $data);
|
|
$len -= $w;
|
|
} while ($len && ($data = substr($data, $w)) !== FALSE);
|
|
}
|
|
|
|
function safe_read($fd, $len)
|
|
{
|
|
$data = '';
|
|
while ($len > 0) {
|
|
$d = fread($fd, $len);
|
|
$len -= strlen($d);
|
|
$data .= $d;
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
function pipe()
|
|
{
|
|
return stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0);
|
|
}
|
|
|
|
function main()
|
|
{
|
|
$begin = microtime(TRUE);
|
|
global $argc, $argv, $parent, $chunk_data_size, $total_data_size, $pipe, $pipes, $_tpl;
|
|
$n = $argc > 2 ? $argv[2] : 1;
|
|
|
|
$procs = 1;
|
|
if (file_exists('/proc/cpuinfo')) {
|
|
$procs = preg_match_all('/^processor\s/m', file_get_contents('/proc/cpuinfo'), $discard);
|
|
}
|
|
|
|
if ($n < $procs) {
|
|
$procs = 1;
|
|
}
|
|
|
|
$chunk_size = (int)($n / $procs);
|
|
$double_size = strlen(pack('d', 0.0));
|
|
$chunk_data_size = $double_size * $chunk_size;
|
|
$total_data_size = $double_size * $n;
|
|
|
|
$pipes = array();
|
|
$parent = FALSE;
|
|
for ($i = 0; $i < $procs; ++$i) {
|
|
$range_begin = $i * $chunk_size;
|
|
if ($i < ($procs - 1)) {
|
|
$pipe = pipe();
|
|
if (!$pipe) {
|
|
die('could not create pipe');
|
|
}
|
|
$pipes[] = $pipe[0];
|
|
$pipe = $pipe[1];
|
|
$range_end = $range_begin + $chunk_size;
|
|
$pid = pcntl_fork();
|
|
if ($pid === -1) {
|
|
die('could not fork');
|
|
} else if ($pid) {
|
|
continue;
|
|
}
|
|
break;
|
|
} else {
|
|
$range_end = $n;
|
|
$parent = TRUE;
|
|
}
|
|
}
|
|
|
|
$u = array_fill(0, $n, 1.0);
|
|
$_tpl = array_fill($range_begin, $range_end - $range_begin, 0.0);
|
|
$sync = $procs > 0;
|
|
|
|
for ($i = 0; $i < 10; $i++) {
|
|
$v = AtAv($n, $u, $range_begin, $range_end, $sync);
|
|
$u = AtAv($n, $v, $range_begin, $range_end, $sync);
|
|
}
|
|
|
|
if (!$parent) {
|
|
exit(0);
|
|
}
|
|
|
|
$childs = $procs - 1;
|
|
while ($childs--) {
|
|
pcntl_wait($s);
|
|
}
|
|
|
|
$vBv = 0.0;
|
|
$vv = 0.0;
|
|
$i = 0;
|
|
foreach ($v as $val) {
|
|
$vBv += $u[$i] * $val;
|
|
$vv += $val * $val;
|
|
++$i;
|
|
}
|
|
printf("%0.9f\n", sqrt($vBv / $vv));
|
|
printf("Time: %.9f\n", microtime(TRUE) - $begin);
|
|
}
|
|
|