[GIT-PULLS] [php-src] PR #23509: [W.I.P] Idea: Specialize floating-point division in the VM and JIT
[email protected] (LamentXU123)
| Newsgroups | php.git-pulls |
|---|---|
| Message-ID | <[email protected]> |
Pull Request: https://github.com/php/php-src/pull/23509
Author: LamentXU123
I am looking into php's floating-point internals recently. This is a demo PR that adds specialized execution paths for floating-point `ZEND_DIV` operations.
Benchmark script:
```php
<?php
function divDoubleDouble(float $x, float $divisor, int $iterations): float
{
for ($i = 0; $i < $iterations; $i++) {
$x = $x / $divisor;
}
return $x;
}
function divDoubleLong(float $x, int $divisor, int $iterations): float
{
for ($i = 0; $i < $iterations; $i++) {
$x = $x / $divisor;
$x = $x + 1.0;
}
return $x;
}
function divLongDouble(float $divisor, int $iterations): float
{
$sum = 0.0;
for ($i = 1; $i <= $iterations; $i++) {
$sum = $sum + $i / $divisor;
}
return $sum;
}
function mulDoubleDouble(float $x, float $factor, int $iterations): float
{
for ($i = 0; $i < $iterations; $i++) {
$x = $x * $factor;
}
return $x;
}
function measure(string $name, Closure $run, int $iterations, int $rounds): void
{
$run();
$best = PHP_INT_MAX;
$checksum = 0.0;
for ($round = 0; $round < $rounds; $round++) {
$start = hrtime(true);
$checksum += $run();
$elapsed = hrtime(true) - $start;
$best = min($best, $elapsed);
}
printf("%-20s %8.3f ns/iter checksum=%.9g\n", $name, $best / $iterations, $checksum);
}
$iterations = (int) ($argv[1] ?? 10_000_000);
$rounds = (int) ($argv[2] ?? 7);
measure('double/double', fn() => divDoubleDouble(12345.6789, 1.000000001, $iterations), $iterations, $rounds);
measure('double/long', fn() => divDoubleLong(12345.6789, 2, $iterations), $iterations, $rounds);
measure('long/double', fn() => divLongDouble(1.000000001, $iterations), $iterations, $rounds);
measure('double*double', fn() => mulDoubleDouble(12345.6789, 0.999999999, $iterations), $iterations, $rounds);
```
Results:
| Mode | Operands | Before (ns/iter) | After (ns/iter) | Improvement |
|---|---|---:|---:|---:|
| VM | float / float | 12.501 | 8.267 | 33.9% |
| VM | float / int | 17.260 | 12.360 | 28.4% |
| VM | int / float | 14.903 | 10.159 | 31.8% |
| Optimizer | float / float | 8.738 | 7.517 | 14.0% |
| Optimizer | float / int | 9.669 | 7.729 | 20.1% |
| Optimizer | int / float | 13.740 | 7.949 | 42.1% |
| Tracing JIT | float / float | 5.397 | 4.573 | 15.3% |
| Tracing JIT | float / int | 6.391 | 6.533 | within noise |
| Tracing JIT | int / float | 6.678 | 2.350 | 64.8% |