← Tutti i video

Ottimizziamo l'allineamento

Guarda su YouTube → 19:04 9 dicembre 2025

Descrizione

Oggi focus su ottimizzazione. Riprendiamo la funzione align_up scritta durante la serie kernel-dev e la riscriviamo, cercando di migliorare le performance. Nel video mostro due implementazioni alternative ad align_up. Andando a rimuovere l'if, riusciamo a migliorare in modo significativo le performance. Un piccolo esempio di ottimizzazione sensata. Se vuoi supportare il mio lavoro, ho un gruppo per la preparazione OSCP: - https://www.patreon.com/hexdump Scopri i miei corsi - https://www.udemy.com/user/leonardo-tamiano-5 Se sei interessato ai miei servizi di formazione: - https://esadecimale.it

Commenti 16

I commenti vengono da YouTube e sono aggiornati periodicamente.

  1. @DiTBho 9 dicembre 2025
    Unico guaio, Div impiega molti cicli clock.
    7 risposte
    1. @esadecimale Autore 9 dicembre 2025
      Puoi sostituire div con un'altra operazione che ti calcola le stesse cose? La versione più ottimizzata non utilizza div, però assumendo di essere interessati a fare alignment arbitrari è possibile rimuovere div?
    2. @DiTBho 9 dicembre 2025
      ​@esadecimaleesattamente il mio dubbio
    3. @DiTBho 9 dicembre 2025
      Fai conto, sui SoC mips32 che utilizzo, div impiega 33 colpi di clock. Decisamente tanti.
    4. @esadecimale Autore 9 dicembre 2025
      ​​​@DiTBhoda un punto di vista pragmatico diciamo ha poco senso fare alignment di valori arbitrari, in quanto la memoria è in potenza di due Quindi ci si salva in quel modo andando di bit operations e togliendo l'if
    5. @zordak112 9 dicembre 2025
      Beh non lo so proprio! anche considerando che l'alignment arbitrario e' spesso inutile. Ma se si conosce a comptime alignment si puo' ridurre la funzione in assembly addirittura a 2 istruzioni! Supponiamo 16 come allineamento standard di molti allocatori di memoria. Almeno per quello che ne so io. align_up: add rdi, 15 ; value + alignment - 1 and rax, -16 ; & bitmask col valore di ~(alignment - 1) ret Non ho testato questa funzione ma ad occhio mi pare corretta. Il compilatore GCC da' una versione simile per la tua stessa funzione con 16 al posto di align hardcoded: align_up: lea rax, [rdi+15] and rax, -16 ret Questo lea in riga 2 mi pare che su versioni nuove di intel sia 3 cicli di clock piu' lento delle vecchie. credo la mia versione risparmi qualcosina. ma non ha tre operandi per cui non si qualifica come un complex lea, che rispetto ai processori nuovi AMD, su intel e' piu' lento. Ma questa cosa e' solo una reminiscenza di quel poco che ho letto su internet, non so se sia vero.
    6. @dontpanic0__ 9 dicembre 2025
      ​@DiTBhosì, algoritmi di divisione usati "hardware" come restoring/non restoring (ancora molto usati per micro controllers e simili) prendono almeno tanti cicli di clock quanta è la lunghezza in bit degli operandi. Tuttavia algoritmi migliori usati dalle CPU commerciali (e.g. SRT e simili) possono avere una latenza sensibilmente inferiore (sempre svariati cicli cmq), ma soprattutto sono "pipelinable" e questo permette di ottenere un throughput decisamente maggiore
    7. @DiTBho 9 dicembre 2025
      ​@dontpanic0__pensa che ne implementati un paio in vhdl per un softcore mips32. Ho circa le stesse performance sulle vecchie fpu Motorola mc68881, e sui SoC mips32 low cost.
  2. @davidesfriso8071 9 dicembre 2025
    Un’altra opzione, comunque non performante come la terza, potrebbe essere: return value + (align - remainder) * (remainder != 0)
    2 risposte
    1. @esadecimale Autore 9 dicembre 2025 1
      Si anche questa funziona. Ad occhio fa div e CMP, quindi probabilmente meno efficiente dell'altra con solo div, però anche questa carina si Oltre al fatto che la terza non si batte ahaha
    2. @davidesfriso8071 9 dicembre 2025
      @esadecimale mi sono “focalizzato” sul togliere l’IF 😅
  3. @robbieonthefly 10 dicembre 2025
    Le coincidenze ultimamente sono assurde. . Proprio l’altro giorno ho scoperto il fenomeno della branch prediction e oggi mi compare il tuo video sull’argomento. Due giorni fa sono tornato a giocare ad among us con amici, e guarda caso uno youtuber che seguivo ha ricominciato a pubblicare video su among us dopo anni. Assurdo. A volte sembra davvero che il mondo giri intorno a me, altro che… HAHAHA. Scherzi a parte, informandomi ho letto che i compilatori gestiscono automaticamente questo tipo di ottimizzazioni. È corretto, oppure ho capito male?
    1 risposta
    1. @esadecimale Autore 10 dicembre 2025
      I compilatori possono automatizzare tanto quando capiscono ciò che stai cercando di fare, ma sono comunque limitati dal contesto. Ad esempio in questo caso il compilatore non ottimizza tanto, bisogna farlo manualmente, perché i calcoli in gioco sono diversi tra loro. Però si ottimizzano tanto, specialmente se metti le flat di ottimizzazione tipo -O3 Per il resto, tecnicamente l'universo non ha un punto centrale, quindi ciascuno di noi può affermare di essere "il centro dell'universo" ahahah
  4. @iacopo.barons 9 dicembre 2025
    Mi ci intrippo su queste robe quindi farò un po' di domande pura curiosità per condividere metodi di prendere le performance. Perché non hai attivato le ottimizzazioni del compilatore? Quindi almeno -O2 e verificato anche da godbolt / compiler Explorer se cambiava qualcosa anche a vari livelli di ottimizzazione come -O3 e -Ofast, Avresti pure potuto controllare se durante uno dei test di una particolare funzione per qualche motivo il kernel avesse fatto più contex switch andando a aumentare il tempo senza però impiegarlo nella computazione, avresti poi potuto provare altri compilatori per vedere se l`assembly generato fosse lo stesso, vedere anche il base all`architettura se l`assembly fosse lo stesso (probabilmente no ma in questo caso ti giustamente l`hai testato sul computer che avevi che presumo sia un x86_64?). Poi per questi benchmark si può utilizzare il registro della CPU che conta i cicli piuttosto che andare a misurare il tempo? Ad alcune domande non ho risposta e vorrei sapere cosa ne pensi :) Edit: Un`altra cosa che mi sta venendo in mente per spremere fino all`osso sarebbe avere diverse funzioni per ogni potenza di 2 che vogliamo allineare così da risparmiarci pure il calcolo della maschera oppure andare a passare alla funzione già la maschera con qualche macro facendo così effettivamente solo 1 operazione and bitwise. Volendo ancora andare oltre potrebbe usare l`inline per ottimizzare pure la chiamata a funzione andandola a togliere (utilizzando le linker optimization se lavoriamo su più file). Potremmo nella funzione benchmark andare a chiamare 1 volta la funzione prima dell`avvio del timer per evitare inavvertitamente un Page faut sulla prima chiamata. Andando puramente a speculare perché non so veramente come funziona possiamo fare direttamente una macro con l`inline assembly per fare un bitwise non dell`intero registro ma solo la parte bassa quindi solo i primi 8 bit (ma qua non so se effettivamente rende l`operazione più veloce o meno oppure se le operazioni bitwise abbiano la stessa durata in termini di clock cycle della CPU indipendente dal registro)
    2 risposte
    1. @esadecimale Autore 9 dicembre 2025 1
      I punti che hai elencato sono tutti interessati. L'ottimizzazione mostrata qui era principale software / computazionale, e non faceva troppi riferimenti all'hardware. A parte l'idea generale di evitare statement condizionali. Personalmente non sono un esperto di hardware. Dalla mia limitata esperienza però ti posso dire che per quanto riguarda le ottimizzazioni è molto semplice cercare di iper-ottimizzare un sistema, ma raramente la iper-ottimizzazione funziona perché poi nei sistemi reali hai tanto rumore, che è veramente difficile da catturare in un ambiente di test. Ci sono però alcune ottimizzazioni, specialmente quelle software, che funzionano meglio a prescindere da considerazioni hardware, per cui io preferisco quelle. Poi ci sono anche ottimizzazioni nell'utilizzo della memoria, ma quelle hanno senso in programmi più grandi, e non prendendo in considerazione una singola funzione. Quindi io l'approccio così: se vedo che c'è un modo migliore facilmente implementabile lo implemento. Se vedo che ho una lentezza eccessiva del programma, provo a vedere dove riesco ad ottimizzare. Altrimenti non spendo troppo tempo nel pensare all'ottimizzazione in modo troppo preciso Ti consiglio una serie di Casey Muratori se ti piacciono queste cose hardware: si chiama Computer Enhance!
    2. @iacopo.barons 10 dicembre 2025
      Daje ci sta é la risposta che volevo avere ahhaha, ci darò sicuramente un`occhiata alla serie di Muratori