[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% |
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.