PHP Academy · Lektion

OPcache och JIT-kompilering

Snabba upp PHP med bytekodscachning och JIT.

Lektion 3 av 413 steg

OPcache och JIT-kompilering är en gratis lektion i PHP Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för PHP Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i PHP Academy innehåller totalt 4 lektioner.

Cachelagrad kompilering

OPcache lagrar kompilerade opcodes i delat minne, så att PHP slipper lexning, parsning och kompilering vid varje anrop. Dessutom kompilerar JIT (sedan PHP 8.0) heta opcodes till inbyggd maskinkod. Tillsammans utgör de ryggraden i PHP:s prestanda.

Den här lektionen behandlar konfiguration av OPcache, preloading och finjustering av JIT.

Vad OPcache gör

Den kompilerade op_array för varje fil cachelagras i ett segment med delat minne som används av alla FPM-workers. Ett anrop som får en cacheträff återanvänder opcodes direkt. OPcache kör också en optimerare (konstantfoldning, eliminering av död kod och opcode-fusion) första gången en fil kompileras.

; Core OPcache config (php.ini)
opcache.enable = 1
opcache.memory_consumption = 256      ; MB of shared memory
opcache.interned_strings_buffer = 16  ; MB for interned strings
opcache.max_accelerated_files = 20000 ; cap on cached scripts

Validering av tidsstämplar

validate_timestamps avgör om OPcache kontrollerar filernas ändringstider igen. I utvecklingsmiljö bör den vara aktiverad med en kort revalidate_freq; i produktion bör den sättas till 0 så att PHP aldrig kontrollerar filer, och nya versioner distribueras genom att cachen rensas eller avbildningen byggs om.

; Production: never re-stat files
opcache.validate_timestamps = 0

; Development: check every 2 seconds
; opcache.validate_timestamps = 1
; opcache.revalidate_freq = 2

Inspektera cachen

opcache_get_status() rapporterar träffkvot, minnesanvändning och cachelagrade skript; opcache_get_configuration() visar inställningarna. En låg träffkvot eller frekventa omstarter innebär att minnet är otillräckligt eller att det finns för många filer.

<?php
if (function_exists('opcache_get_status')) {
    $s = opcache_get_status(false);
    if ($s) {
        printf("hits:   %d\n", $s['opcache_statistics']['hits']);
        printf("misses: %d\n", $s['opcache_statistics']['misses']);
        printf("hit %%: %.2f\n", $s['opcache_statistics']['opcache_hit_rate']);
        printf("used:   %.1f MB\n", $s['memory_usage']['used_memory'] / 1048576);
    } else {
        echo "OPcache enabled but no status (likely CLI)\n";
    }
} else {
    echo "OPcache not available\n";
}
?>

Preloading

Preloading (PHP 7.4+) kompilerar en uppsättning klasser och funktioner en gång när servern startar och behåller dem permanent i minnet. De blir då tillgängliga för varje anrop utan autoloading eller länkning per anrop. Ange ett skript i opcache.preload som kräver in filerna för att värma upp cachen.

; php.ini
opcache.preload = /app/preload.php
opcache.preload_user = www-data

Skriva ett preload-skript

Preload-skriptet körs i huvudprocessen. Använd opcache_compile_file() för att läsa in klasser utan att köra dem, eller använd helt enkelt require. Ramverk genererar en preload-lista; så här ser en sådan i princip ut.

<?php
// preload.php — runs once at startup
$dir = '/app/src';
$rii = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($dir)
);

foreach ($rii as $file) {
    if ($file->getExtension() === 'php') {
        // Compiles + links the class into shared memory
        opcache_compile_file($file->getPathname());
    }
}
?>

JIT gör entré

Även med cachelagrade opcodes tolkar VM:en dem fortfarande. JIT kompilerar heta opcode-sekvenser till inbyggda CPU-instruktioner och eliminerar därmed VM:ens dispatch-omkostnad. Vinsten är stor för CPU-bunden numerisk kod, men måttlig för typiska I/O-bundna webbappar, som tillbringar tiden i databasen eller nätverket snarare än på CPU:n.

Konfigurera JIT

JIT finns inuti OPcache, så OPcache måste vara aktiverat. opcache.jit_buffer_size reserverar utrymme för genererad maskinkod (0 inaktiverar JIT). opcache.jit är ett fyrsiffrigt läge som styr utlösare och optimeringsstrategi.

; Enable JIT (requires opcache.enable=1)
opcache.jit_buffer_size = 128M
opcache.jit = tracing        ; alias for 1254, the common default

; The 4 digits CRTO mean:
;   C - CPU optimization flags
;   R - register allocation
;   T - trigger (when to JIT)
;   O - optimization level

Tracing JIT kontra function JIT

Det finns två strategier: function JIT (läget 1205) kompilerar hela funktioner vid det första anropet; tracing JIT (1254, standardaliaset tracing) profilerar körningen och kompilerar heta loopar och körvägar. Det ger ofta bättre resultat eftersom optimeringen specialiseras utifrån observerade typer. Tracing är det rekommenderade standardalternativet.

; Tracing JIT (recommended) — compiles hot traces
opcache.jit = tracing

; Function JIT — compiles entire functions when first called
; opcache.jit = function

; Disable JIT but keep opcode cache
; opcache.jit_buffer_size = 0

Mäta JIT:s påverkan

JIT gör störst skillnad i täta numeriska loopar. Detta fristående benchmark, en Mandelbrot-liknande inre loop, är ett exempel på en CPU-bunden arbetsbelastning där JIT kan minska körtiden avsevärt. Kör det med och utan jit_buffer_size för att jämföra.

<?php
function mandelEscape(float $cr, float $ci, int $max): int {
    $zr = 0.0; $zi = 0.0; $n = 0;
    while ($n < $max && ($zr * $zr + $zi * $zi) <= 4.0) {
        $t  = $zr * $zr - $zi * $zi + $cr;
        $zi = 2.0 * $zr * $zi + $ci;
        $zr = $t;
        $n++;
    }
    return $n;
}

$start = hrtime(true);
$sum = 0;
for ($y = 0; $y < 200; $y++) {
    for ($x = 0; $x < 200; $x++) {
        $sum += mandelEscape($x / 100 - 2, $y / 100 - 1, 256);
    }
}
printf("sum=%d  time=%.2f ms\n", $sum, (hrtime(true) - $start) / 1e6);
?>

När ni INTE bör förvänta er vinster

För ett typiskt anrop som frågar en databas, renderar en mall och returnerar JSON utför CPU:n inte mycket ren aritmetik — JIT kan ge ensiffriga procentuella förbättringar eller inga alls. Prioritera OPcache, preloading och god användning av databaser och cacher först. Reservera JIT-justeringar för bildbehandling, matematik, parserar och annan beräkningsintensiv kod.

Snabb kontroll

Vad ger preloading som vanlig OPcache-cachelagring inte ger?

Sammanfattning

OPcache cachelagrar kompilerade op_arrays i delat minne och kör en optimerare. Sätt validate_timestamps=0 i produktion och dimensionera memory_consumption/max_accelerated_files korrekt. Preloading håller utvalda klasser kvar i minnet vid uppstart. JIT (inuti OPcache och beroende av jit_buffer_size) kompilerar het kod till inbyggda instruktioner — stora vinster för CPU-bunden matematik, men små vinster för I/O-bundna webbappar. Använd opcache_get_status() för att verifiera konfigurationen.

Gratis att börja

Lär dig PHP med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
49
Lektioner
195

Vanliga frågor

Är lektionen ”OPcache och JIT-kompilering” gratis?

Ja – hela texten till ”OPcache och JIT-kompilering” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i PHP Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i PHP Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”OPcache och JIT-kompilering”?

Snabba upp PHP med bytekodscachning och JIT. Ni övar på PHP Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig PHP Academy?

Du behöver inga förkunskaper. Utbildningen i PHP Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”OPcache och JIT-kompilering”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här PHP Academy-lektionen?

Ja. Varje PHP Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Så fungerar Zend Engine
  2. Minneshantering och skräpsamling
  3. OPcache och JIT-kompilering
  4. Skriva ett grundläggande PHP-tillägg i C
← Tillbaka till PHP Academy