source code
<?php
/* The Computer Language Benchmarks Game
https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
multicore version
algorithm is based on Java 6 source code by Oleg Mazurov
fork/shared mem is based on mandelbrot.php-3
contributed by Oleksii Prudkyi
work-around GH-7899 regression by therealgaxbo
*/
$n = (int) $argv[1];
$count_base = array();
$p_base = range(0, $n - 1);
$procs = 1;
if (file_exists('/proc/cpuinfo')) {
$procs = preg_match_all('/^processor\s/m', file_get_contents('/proc/cpuinfo'), $discard);
}
$procs <<= 1;
$Fact = array(1);
for ($i = 1, $j = 0; $i <= $n; $j = $i++) {
$Fact[$i] = $Fact[$j] * $i;
}
$index = 0;
$index_max = $Fact[$n];
$index_step = intval(($index_max + $procs-1) / $procs);
$shsize = $procs * 16;
$shmop = shmop_open(ftok(__FILE__, chr(time() & 255)), 'c', 0644, $shsize);
if (!$shmop) {
echo "faild to shmop_open()\n";
exit(1);
}
for ($proc = 0; $proc < $procs; ++$proc, $index += $index_step ) {
if($proc < $procs - 1) {
$pid = pcntl_fork();
if ($pid === -1) {
die('could not fork');
} else if ($pid) {
continue;
}
}
$idxMin = $index;
$idxMax = min( $index_max, $index + $index_step );
//firstPermutation( idxMin );
$count = $count_base;
$p = $p_base;
$idx = $idxMin;
for ($i = $n - 1; $i > 0; --$i ) {
$factI = $Fact[$i];
$reminder = $idx % $factI;
$d = (($idx- $reminder) / $factI);
$count[$i] = $d;
$idx = $reminder;
$pp = $p;
for ($j=0, $jd = $d; $j<=$i; ++$j, ++$jd ) {
$p[$j] = $pp[($jd <= $i) ? $jd :$jd-$i-1];
}
}
$maxflips = 1;
$chksum = 0;
$sign = 1;
for ($idx =$idxMin;; ) {
$first = $p[0];
if ( $first != 0 ) {
//int flips = countFlips();
$flips = 1;
if ( $p[$first] != 0 ) {
$pp = $p;
$p0 = $first;
do {
++$flips;
if ($p0 >= 3){
$i = 1; $j = $p0 - 1;
do {
$t = $pp[$i];
$pp[$i] = $pp[$j];
$pp[$j] = $t;
++$i;
--$j;
} while ($i < $j);
}
$t = $pp[$p0];
$pp[$p0] = $p0;
$p0 = $t;
} while ( $pp[$p0] != 0 );
}
$maxflips = max( $maxflips, $flips );
$chksum += $sign*$flips;
}
++$idx ;
if ( $idx == ($idxMax) ) {
break;
}
if ($sign == 1){
$p[0] = $p[1];
$p[1] = $first;
$sign = -1;
} else {
$t = $p[1];
$p[1] = $p[2];
$p[2] = $t;
$sign = 1;
for($i=2;;){
$sx = &$count[$i];
++$sx;
if ($sx <= $i) {
break;
} else {
$sx = 0;
for($j=0; $j<=$i; ){ $p[$j++] = $p[$j]; }
++$i;
$p[$i] = $first;
$first = $p[0];
}
}
}
}
$written_size = shmop_write($shmop, pack("PP", $maxflips, $chksum), $proc * 16);
if($pid === 0) {
exit(0);
}
}
$child = $procs - 1;
$status = 0;
while ($child-- > 0) {
pcntl_wait($status);
}
$offset = 0;
$res = 0;
$chk = 0;
for ($proc = 0; $proc < $procs; ++$proc, $offset += 16 ) {
list($v, $chk_v) = array_values(unpack('Pa/Pb', shmop_read($shmop, $offset, $written_size)));
$res = max( $res, $v );
$chk += $chk_v;
}
printf("%d\nPfannkuchen(%d) = %d\n", $chk, $n, $res);
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
PHP 8.4.1 (cli)
(built: Nov 22 2024 14:22:47) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.1,
with Zend OPcache v8.4.1,
Copyright (c) Zend Technologies
Sat, 23 Nov 2024 04:23:46 GMT
COMMAND LINE:
/opt/src/php-8.4.1/bin/php -dzend_extension=/opt/src/php-8.4.1/lib/php/extensions/no-debug-non-zts-20240924/opcache.so -dopcache.enable_cli=1 -dopcache.jit_buffer_size=64M -n fannkuchredux.php-4.php 12
PROGRAM OUTPUT:
3968050
Pfannkuchen(12) = 65