Skip to content

Instantly share code, notes, and snippets.

@rickynguyen4590
Created March 2, 2021 17:26
Show Gist options
  • Save rickynguyen4590/e1db0f9c055b0f2a5b63db2664ea142b to your computer and use it in GitHub Desktop.
Save rickynguyen4590/e1db0f9c055b0f2a5b63db2664ea142b to your computer and use it in GitHub Desktop.
Multiple matrix with pthread
<?php
class MatrixThreaded extends Threaded
{
public function __construct($rowIndex, $row, $matrix2)
{
$this->rowIndex = $rowIndex;
$this->row = $row;
$this->matrix2 = $matrix2;
$this->rowResult = [];
$this->done = false;
}
public function run()
{
$c = count($this->matrix2[0]);
$p = count($this->matrix2);
for ($j = 0; $j < $c; $j++) {
$this->rowResult[$j] = 0;
for ($k = 0; $k < $p; $k++) {
$this->rowResult[$j] += $this->row[$k] * $this->matrix2[$k][$j];
}
}
$this->done = true;
}
public function getResult()
{
return $this->rowResult;
}
public function getRowIndex()
{
return $this->rowIndex;
}
public function isDone(): bool
{
return $this->done;
}
}
class MatrixPool extends Pool
{
protected $result = [];
public function process($matrix1, &$matrix2)
{
$r = count($matrix1);
for ($i = 0; $i < $r; $i++) {
$this->submit(new MatrixThreaded($i, $matrix1[$i], $matrix2));
}
while(count($this->result) < $r) {
$this->collect(function (MatrixThreaded $threaded) {
if ($threaded->isDone()) {
$this->result[$threaded->getRowIndex()] = $threaded->getResult();
}
return $threaded->isDone();
});
}
$this->shutdown();
return $this->result;
}
}
function matrix_gen($row, $col)
{
$result = [];
for ($i = 0; $i < $row; $i++) {
$column = [];
for ($j = 0; $j < $col; $j++) {
$column[] = rand(1, 9);
}
$result[] = $column;
}
return $result;
}
function matrix_mult($m1, $m2): array
{
$r = count($m1);
$c = count($m2[0]);
$p = count($m2);
if (count($m1[0]) != $p) {
throw new Exception('Incompatible matrixes');
}
$m3 = [];
for ($i = 0; $i < $r; $i++) {
for ($j = 0; $j < $c; $j++) {
$m3[$i][$j] = 0;
for ($k = 0; $k < $p; $k++) {
$m3[$i][$j] += $m1[$i][$k] * $m2[$k][$j];
}
}
}
return ($m3);
}
function compare_matrix($m1, $m2): bool
{
$r = count($m1);
$c = count($m1[0]);
if (count($m2) !== $r || count($m2[0]) !== $c) {
return false;
}
for ($i = 0; $i < $r; $i++) {
for ($j = 0; $j < $c; $j++) {
if ($m1[$i][$j] !== $m2[$i][$j]) {
return false;
}
}
}
return true;
}
$matrix_1 = matrix_gen(100, 1000);
$matrix_2 = matrix_gen(1000, 100);
$start = microtime(true);
$matrix_3 = matrix_mult($matrix_1, $matrix_2);
$result = microtime(true) - $start;
echo sprintf("normal: %f \n", $result);
$start = microtime(true);
$pool = new MatrixPool(8);
$matrix_4 = $pool->process($matrix_1, $matrix_2);
$result = microtime(true) - $start;
$label = compare_matrix($matrix_3, $matrix_4) ? 'pthread' : 'pthread (incorrect): ';
echo sprintf("%s: %f \n", $label, $result);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment