Skip to content

Instantly share code, notes, and snippets.

@krakjoe
Last active October 8, 2015 08:53
Show Gist options
  • Select an option

  • Save krakjoe/9274747 to your computer and use it in GitHub Desktop.

Select an option

Save krakjoe/9274747 to your computer and use it in GitHub Desktop.
mandel pthreads

This is a rather extreme test ... still, was fun ...

[joe@fiji pthreads]$ time php-zts ../php-src/mandrel.php 0 128

real	0m11.441s
user	0m11.386s
sys	0m0.043s
[joe@fiji pthreads]$ time php-zts ../php-src/mandrel.php 1 128

real	0m2.951s
user	0m21.308s
sys	0m0.243s
[joe@fiji pthreads]$ time php-zts ../php-src/mandrel.php 0 256

real	0m19.072s
user	0m19.010s
sys	0m0.044s
[joe@fiji pthreads]$ time php-zts ../php-src/mandrel.php 1 256

real	0m4.786s
user	0m36.023s
sys	0m0.247s

I used as many threads as I have cores, the only sensible number to use ;)

mandel

<?php
/*
* requires pthreads, obviously !!
* usage:
* php mandel.php 1 128 - run with threads, 128 iterations
* php mandel.php 0 128 - run without threads, 128 iterations
* Disclaimer: I know nothing about images, code from:
* http://code.activestate.com/recipes/577680-multi-threaded-mandelbrot-fractal/
*/
class Render extends Thread {
public function __construct(Mandel $mandel, $id, $max, $img) {
$this->mandel = $mandel;
$this->id = $id;
$this->max = $max;
$this->img = $img;
}
public function run() {
$mandel = $this->mandel;
$iterations = $mandel->getIterations();
$range = range(
$this->id,
$mandel->getSum(),
$this->max);
$width = $mandel->getWidth();
$height = $mandel->getHeight();
$draw = $mandel->getDraw();
$image = $this->img;
foreach ($range as $pixel) {
$kx = $pixel % $width;
$ky = (int) $pixel / $width;
$a = $draw["xa"] +
$draw["xd"] * $kx / ($width - 1.0);
$b = $b = $draw["ya"] +
$draw["yd"] * $ky / ($height - 1.0);
$x = $a;
$y = $b;
for ($it = 0; $it < $iterations; $it++) {
$x0 = $x * $x - $y * $y + $a;
$y = 2.0 * $x * $y + $b;
$x = $x0;
if ($x * $x + $y * $y > 4) {
$c = imagecolorallocate(
$image,
($it % 8) * 32,
(16 - $it % 16) * 16,
($it % 16) * 16);
imagesetpixel(
$image, $kx, $ky, $c);
break;
}
}
}
}
protected $mandel;
protected $id;
protected $max;
protected $img;
}
class Mandel extends Stackable {
public function __construct($width, $height, $iterations) {
$this->width = $width;
$this->height = $height;
$this->sum = $this->width *
$this->height;
$this->iterations = $iterations;
$this->draw = [
"xa" => -2,
"xb" => 1.0,
"ya" => -1.5,
"yb" => 1.5,
"xd" => 1.0 - (-2),
"yd" => 1.5 - (-1.5)
];
}
public function getIterations() { return $this->iterations; }
public function getDraw() { return $this->draw; }
public function getSum() { return $this->sum; }
public function getWidth() { return $this->width; }
public function getHeight() { return $this->height; }
public function createImage() {
return imagecreatetruecolor(
$this->width, $this->height);
}
public function run(){}
protected $width;
protected $height;
protected $sum;
protected $iterations;
protected $draw;
}
$threaded = isset($argv[1]) ? intval($argv[1]) : 1;
$iterations = isset($argv[2]) ? intval($argv[2]) : 64;
$mandel = new Mandel(1920, 1280, $iterations);
$image = $mandel->createImage();
$threads = []; # array of threads
$thread = 0; # current thread identifier
$max = 8; # maximum number of threads
while ($thread<$max) { # create all threads, or not
$threads[$thread] = new Render(
$mandel, $thread, $max, $image);
if (!$threaded) {
$threads[$thread]->run();
} else $threads[$thread]->start();
$thread++;
}
if ($threaded) {
foreach ($threads as $thread)
$thread->join();
}
imagepng($image, "mandel.png"); # dump image
?>
@DeeFuse

DeeFuse commented Jun 15, 2015

Copy link
Copy Markdown

If you want to render Larger images, you may get into memory allocation trouble because of the huge amount of items in $range.
Also the statement $image = $this->img; will use a lot of memory.

I would suggest removing L24-L27 and L31
Replacing L33 with:

        for($pixel=$this->id;$pixel<=$mandel->getSum();$pixel+=$this->max) {

And $imagein L49 and L55 with $this->img

With this changes I've made a 15306x10240px @ 8 Threads with 256 Iterations without problems.

@Jan-E

Jan-E commented Oct 8, 2015

Copy link
Copy Markdown

https://gist.github.com/krakjoe/9274747#file-mandel-php-L68 should be

class Mandel extends Threaded {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment