ELAI S.r.l.

Il processore non è pieno: perché l’inferenza perde la scadenza?

Un esempio eseguito confronta priorità fisse, scadenze dinamiche e blocchi: capire quando la capacità media non basta a consegnare una risposta AI in tempo.

Il processore non è pieno: perché l’inferenza perde la scadenza?

Il tempo libero può arrivare troppo tardi

Un dispositivo controlla un sensore e, sullo stesso processore, esegue periodicamente un modello AI. Il conteggio del lavoro dice che la capacità complessiva basta: il processore non dovrebbe restare occupato per tutto il tempo. Eppure una risposta arriva dopo l’istante in cui serviva. Non c’è contraddizione. Il tempo libero può trovarsi dopo la scadenza, mentre nell’intervallo utile un compito prioritario interrompe l’inferenza. Per capire il problema non basta chiedere quanti millisecondi richieda il modello da solo: occorre chiedere quando gli viene concesso di usarli.

Studieremo due compiti con numeri deliberatamente semplici, ricostruendo ogni intervallo di esecuzione. Confronteremo una priorità fissata in anticipo con una regola che guarda alla scadenza più vicina. Poi ridurremo il tempo di calcolo dell’AI e aggiungeremo un breve blocco iniziale per vedere quale margine rimane. Sono tempi sintetici di un simulatore, non misure su microcontrollori o acceleratori. Alla fine sapremo distinguere capacità media, tempo di calcolo e tempo di risposta, e leggere un ritardo senza attribuirlo subito al modello neurale.

Tre orologi diversi nello stesso dispositivo

Un task è un’attività ricorrente, come leggere ed elaborare il sensore. Ogni sua attivazione concreta è un job, cioè una singola richiesta di lavoro. Il periodo T indica ogni quanto viene rilasciata una richiesta; il costo C è il tempo di processore necessario a completarla senza interruzioni; la scadenza relativa D è quanto possiamo aspettare dal rilascio. Il tempo di risposta R va invece dal rilascio al completamento effettivo e comprende anche le attese. Tutte queste quantità sono espresse qui in millisecondi, abbreviati ms: un millisecondo è un millesimo di secondo.

Assegniamo al sensore S un costo di 2 ms ogni 5 ms e all’inferenza AI un costo di 4,5 ms ogni 8 ms. Entrambi devono finire prima della richiesta successiva, quindi D coincide con T. Partono insieme all’istante zero. Supponiamo un solo nucleo di calcolo, attività indipendenti, costi costanti, nessuna attesa di memoria o acceleratore e interruzioni immediate senza costo di cambio. Queste ipotesi rendono il problema analizzabile; non descrivono automaticamente un sistema operativo o una scheda. In particolare, 4,5 ms è un dato scelto dell’esperimento, non un tempo massimo dimostrato per un modello reale.

AttivitàC (ms)T (ms)D (ms)
S255
AI4.588

La capacità media dice quanto lavoro c’è, non quando finirà

Per controllare il carico complessivo dividiamo il costo di ogni attività per il suo periodo e sommiamo. C/T è una frazione senza unità: il sensore richiede due millisecondi di calcolo ogni cinque disponibili, dunque il 40% del processore. L’AI richiede 4,5/8, cioè il 56,25%. La somma è 96,25%, inferiore al 100%. Questa verifica esclude che il lavoro periodico ecceda mediamente la capacità, ma non stabilisce ancora se la regola di priorità lo collochi negli intervalli giusti.

U = C_S / T_S + C_AI / T_AI U = 2/5 + 4.5/8 = 0.9625 = 96.25%

Guardiamo anche un intervallo di 40 ms, multiplo comune di 5 e 8. Vi arrivano otto richieste S e cinque AI, per 8 × 2 + 5 × 4,5 = 38,5 ms di lavoro. Restano 1,5 ms. Se però una risposta serviva a 8 ms, un vuoto trovato a 39 ms non la salva. L’analogia è una giornata di appuntamenti: avere mezz’ora libera alla sera non permette di rispettare due appuntamenti incompatibili al mattino. Qui la differenza è che possiamo interrompere e riprendere un calcolo; proprio questa possibilità verrà usata dalle regole che confrontiamo.

Priorità fissa: seguiamo il primo job fino al ritardo

La prima regola assegna priorità maggiore all’attività con periodo minore: S precede sempre AI. Si chiama rate monotonic, abbreviato RM, perché ordina le priorità secondo la frequenza di attivazione. A tempo zero il sensore occupa l’intervallo 0–2 ms. L’AI lavora da 2 a 5 e completa 3 dei suoi 4,5 ms. A 5 arriva un nuovo S che la interrompe fino a 7. L’AI riprende e termina a 8,5: mezzo millisecondo dopo la scadenza. Ha effettivamente consumato solo 4,5 ms, ma ne ha trascorsi 8,5 fra rilascio e completamento.

Il processore non è guasto e non ha rallentato: ha eseguito esattamente la regola assegnata. Il nuovo sensore rilasciato a 5 ms ha scadenza a 10, mentre il vecchio job AI ha scadenza a 8. La priorità fissa non considera questa urgenza relativa e fa passare prima il sensore. È qui che nasce il controesempio a «carico sotto il 100%, quindi tutto in tempo». Nel simulatore i job scaduti non vengono cancellati: completano il loro lavoro e il ritardo viene registrato, evitando di nascondere la violazione eliminando la richiesta.

Contare le interruzioni prima di conoscere la durata

Possiamo ricostruire il risultato con un calcolo iterativo. La risposta dell’AI deve contenere i suoi C millisecondi e il lavoro di tutti i sensori che la precedono. Se la risposta dura R, nell’intervallo che parte da zero arrivano ceil(R/5) job S, ciascuno da 2 ms. ceil arrotonda all’intero superiore. Il nuovo valore stimato di R dipende quindi dalla stima precedente. Iniziamo dal solo costo dell’AI e ripetiamo fino a quando il conteggio non cambia: abbiamo trovato un punto fisso, cioè un valore che riproduce se stesso nella relazione.

R[0] = C_AI R[k+1] = C_AI + 2 × ceil(R[k] / 5) 4.5 → 6.5 → 8.5 → 8.5 ms

Con 4,5 ms ipotizzati conta un sensore e otteniamo 6,5. Ma un intervallo di 6,5 ms include anche il rilascio del sensore a 5: i sensori diventano due e il totale sale a 8,5. In 8,5 ms restano due, quindi il calcolo si ferma. Il job rilasciato esattamente all’istante di completamento non ritarda quello già completato: questa convenzione spiega perché compare ceil e perché gli estremi degli intervalli contano. La verifica della scadenza è R ≤ D. Qui 8,5 > 8 e il fallimento è esplicito, pur essendo C = 4,5 molto inferiore a D.

Per il nostro insieme di compiti indipendenti, periodici e interrompibili, l’avvio simultaneo è il caso critico della priorità fissa: concentra le richieste più prioritarie davanti a quella osservata. Non estendiamo questa conclusione a qualunque sistema con lock, sospensioni o acceleratori. Il lavoro classico di C. L. Liu e James W. Layland, pubblicato nel Journal of the ACM nel 1973, fornisce il riferimento teorico per queste ipotesi e per il confronto fra priorità fisse e guidate dalle scadenze. È un’analisi matematica, non un benchmark moderno di inferenza; la nostra simulazione usa dati scelti separatamente.

Cambiare l’ordine, mantenendo lo stesso lavoro

La seconda regola sceglie il job pronto con scadenza assoluta più vicina. È Earliest Deadline First, EDF: «prima chi deve finire prima». La scadenza assoluta è rilascio più D, non soltanto D. Fino a 5 ms la sequenza è identica. A 5, però, l’AI già in corso deve finire a 8 e il nuovo sensore a 10. EDF lascia proseguire AI fino a 6,5; poi serve il sensore, che termina a 8,5, ancora prima della propria scadenza. Non abbiamo accelerato nessun calcolo. Abbiamo spostato un’interruzione che la prima regola imponeva troppo presto.

Nel periodo simulato di 40 ms, EDF completa tutte le richieste entro le rispettive scadenze. Per compiti ideali con le ipotesi indicate, il risultato classico lega la fattibilità EDF a U ≤ 1; questo non autorizza a usare il 100% di una scheda reale ignorando il costo delle interruzioni. La simulazione conferma il nostro caso, mentre il teorema ha ipotesi più precise di uno slogan sul carico. Una politica dinamica richiede inoltre un’implementazione corretta e una gestione definita dei sovraccarichi: non sostituisce l’analisi delle risorse effettive.

Mezzo millisecondo in meno può eliminare il ritardo, non creare margine

Torniamo a RM e riduciamo il solo costo AI da 4,5 a 4 ms. Ora U = 2/5 + 4/8 = 0,9. Il calcolo iterativo diventa 4 → 6 → 8 → 8. L’AI termina esattamente alla scadenza. Il simulatore non registra violazioni nei 40 ms, ma il margine del primo job è zero. In un progetto reale, sostituire un costo assunto con una media misurata trasformerebbe questa uguaglianza in una rassicurazione ingiustificata: basta una durata maggiore, un cambio di contesto non contato o un’altra fonte di interferenza per modificare l’esito.

Il noto limite sufficiente RM per due compiti, 2(√2 − 1), vale circa 0,8284 nelle ipotesi classiche. Superarlo non significa che ogni insieme di compiti fallisca: significa che quel test generale non basta più a garantire la fattibilità. Il nostro caso al 90% che rispetta le scadenze è un esempio concreto della distinzione. Invece osservare una richiesta completata oltre D è una prova di fallimento di quella configurazione simulata. Una condizione sufficiente non soddisfatta e una violazione effettiva sono evidenze diverse e devono essere descritte con parole diverse.

Un breve blocco cambia il problema

Nell’ultima variante conserviamo C_AI = 4 ms ma imponiamo un intervallo iniziale di 1 ms in cui nessuno dei due compiti può eseguire. È uno scenario astratto di occupazione non interrompibile già presente al rilascio; non è una simulazione di mutex o di uno specifico driver. S ora esegue da 1 a 3, AI da 3 a 5, il secondo S da 5 a 7 e AI da 7 a 9. L’inferenza perde la scadenza anche se i due compiti periodici richiedono ancora il 90% della capacità. Il lavoro estraneo di 1 ms è aggiuntivo e viene contato nella traccia.

R[0] = C_AI + B R[k+1] = C_AI + B + 2 × ceil(R[k] / 5) B = 1 ms: 5 → 7 → 9 → 9 ms

B indica soltanto il blocco iniziale imposto in questa variante. Non abbiamo dimostrato che 1 ms sia il massimo blocco possibile di un sistema reale, né analizzato tutti i protocolli di sincronizzazione. In 40 ms il lavoro periodico è 36 ms e il blocco aggiunge 1 ms: il totale eseguito è 37 ms, non 36. Il confronto serve a mostrare che il lavoro non interrompibile deve entrare nel modello e che un diagramma completo evita di confondere il carico delle attività selezionate con tutto ciò che occupa il processore.

Leggere il diagramma senza confondere le richieste

La figura mostra i primi 12 ms delle quattro simulazioni, mentre il file dei risultati conserva tutti i 40 ms. Blu indica esecuzione del sensore, verde esecuzione AI, arancione il blocco iniziale. La linea verticale rossa è la scadenza del primo job AI e il punto nero il suo completamento. Il verde che prosegue dopo il punto appartiene ad altre richieste: il colore identifica l’attività, non un singolo job. Le suddivisioni di mezzo millisecondo sono unità del simulatore, non interruzioni misurate. Confrontando le prime due righe si vede lo stesso lavoro disposto diversamente.

Tracce sintetiche su un solo nucleo. Punto nero: completamento del primo job AI; linea rossa: sua scadenza. Stesso colore può indicare richieste diverse. Nessun benchmark hardware.
Tracce sintetiche su un solo nucleo. Punto nero: completamento del primo job AI; linea rossa: sua scadenza. Stesso colore può indicare richieste diverse. Nessun benchmark hardware.

Il simulatore usa tick interi da 0,5 ms, così tutte le durate e i rilasci dell’esempio cadono sulla griglia senza arrotondamenti temporali. A ogni tick inserisce le nuove richieste, sceglie il job secondo RM o EDF e sottrae un tick di lavoro residuo. Registra rilascio, scadenza e completamento per ogni richiesta. Gli assert verificano 8,5, 6,5, 8 e 9 ms per i primi job AI delle quattro varianti, oltre all’assenza di violazioni nei casi EDF e RM da 4 ms senza blocco. Il numero di richieste in ritardo è salvato come risultato della traccia, non come probabilità di guasto.

Che cosa resta da sapere prima di parlare di una scheda

Nel dispositivo reale il primo dato difficile è C. Il tempo medio misurato su alcuni ingressi non è automaticamente un limite superiore. Operatori con percorsi diversi, memoria contesa, interruzioni, frequenza variabile e temperatura possono cambiare il lavoro osservato. Una valutazione dovrebbe dichiarare piattaforma, versione del runtime e del modello, compilatore, clock, ingressi, batch, thread e condizioni di misura. Se l’inferenza usa un acceleratore, attendere il suo completamento non equivale sempre a occupare la CPU: il nostro modello a un solo processore non può essere applicato sostituendo indiscriminatamente un tempo totale a C.

Anche l’arrivo delle richieste può differire dall’ipotesi periodica. Una comunicazione genera raffiche, un sensore consegna dati a blocchi, una fase di acquisizione ritarda il rilascio dell’inferenza. La scadenza dell’intero sistema può partire dalla misura fisica, mentre R in questo articolo parte dal rilascio del job. Il tempo trascorso prima del rilascio non scompare: va aggiunto al percorso sensore-risposta, insieme alle comunicazioni e all’attuazione pertinenti. Non abbiamo simulato questi elementi e non attribuiamo al risultato una garanzia temporale end-to-end.

Quale intervento risponde alla causa osservata?

Ridurre C con un modello più piccolo può aiutare, come mostra la variante da 4 ms, ma deve preservare l’utilità predittiva e includere gli altri costi. Cambiare priorità agisce invece sull’ordine: EDF migliora il nostro caso senza cambiare il modello. Ridurre sezioni non interrompibili agisce su B, mentre spostare attività su un altro nucleo introduce un problema nuovo di comunicazione e risorse condivise. Non sono rimedi intercambiabili. Il diagramma serve a scegliere quale ipotesi investigare, prima di acquistare hardware più potente o attribuire la responsabilità alla sola rete neurale.

Un test futuro sul dispositivo dovrebbe misurare separatamente esecuzione e risposta, registrare i rilasci e le preemption e includere gli scenari di interferenza previsti. Andrebbero confrontati i risultati con un budget temporale esplicito, mantenendo distinti media, percentili e limiti dimostrabili. Qui non esistono misure di potenza, energia per inferenza, picco RAM o prestazioni di una scheda. L’embedded è un ambito editoriale e di interesse da esplorare: questo studio non dimostra prodotti o installazioni EL-AI già disponibili. Non è stato eseguito un test fisico e non viene dichiarata una certificazione.

La risposta: avere tempo non basta, bisogna averlo prima della scadenza

Il processore può avere capacità libera e consegnare comunque una risposta in ritardo perché la capacità è una quantità complessiva, mentre la scadenza riguarda un intervallo preciso. Nel nostro esempio il 96,25% di carico produce un primo completamento a 8,5 ms con RM e a 6,5 ms con EDF, a parità di lavoro. Portare il costo AI a 4 ms elimina il ritardo RM ma lascia margine zero; un blocco iniziale di 1 ms lo fa riapparire. La conclusione operativa è ricostruire il percorso temporale completo e le regole di accesso al processore, oltre a misurare il modello isolato.

Fonti, codice e riproducibilità

Il programma e i risultati sono scaricabili sotto il listato. L’esperimento è deterministico, senza seme casuale. Il frammento stampa carico periodico, risposta del primo job e numero di ritardi per ciascun caso, poi le iterazioni del calcolo. Le versioni usate sono Python 3.14.0 e Matplotlib 3.11.2. Il riferimento storico è una pubblicazione del 1973, non una novità della ricerca del 2026; sono state lette ipotesi, dimostrazioni pertinenti e limiti, senza presentare il nostro esempio come riproduzione di misure degli autori.

C. L. Liu & James W. Layland (1973), Scheduling Algorithms for Multiprogramming in a Hard-Real-Time Environment, Journal of the ACM 20(1), 46–61; DOI 10.1145/321738.321743.

from experiment import run
r = run()
for name, case in r['cases'].items():
    print(name, case['periodic_utilization'],
          case['first_AI_response_ms'], case['late_jobs'])
print(r['recurrences'])

Codice, dati e istruzioni · JSON. Calcoli didattici eseguiti con Python 3.14.0; figure con Matplotlib 3.11.2. Analisi con assistenza AI, senza dichiarare peer review o revisione umana. Copertina originale ImageGen, illustrativa: non documenta persone, sedi o installazioni EL-AI. Fonti consultate il 9 ottobre 2026.