The microest optimization wrt pointer tagging
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
- Tipo di issue
- Documentazione
- Chiarezza
- Da chiarire
- Stato di attività
- Ferma
- Stack tecnologico
- haskell
- Ambito
- compilers, documentation, performance
Direzione di ricerca
Inizia con l’esempio X.hs e riproduci il comando di compilazione di GHC dell’issue per esaminare il Cmm generato. Determina se l’ordinamento dei costruttori e il pointer tagging giustificano una sezione nell’optimization-handbook, quindi documenta la conclusione supportata e qualsiasi evidenza nel contenuto appropriato del libro; nell’issue non è specificato alcun file di destinazione.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
I had a thought recently about something that affects runtime performance, but possibly in such a way so minimal that it might not even be worth adding to the book.
Nonetheless...
GHC tags pointers to evaluated heap-allocated data types with their tag. So, for example, pointers to heap-allocated Maybes will be tagged with +1 if the allocated-value is Nothing and with +2 if it is Just ..., (and with +0 if it is a thunk, in which case we evaluate the thunk which will return a tagged pointer (with either +1 or +2)).
{-# LANGUAGE MagicHash #-}
import Prelude(print)
import GHC.Exts
data Maybe a = Nothing
| Just a
{-# NOINLINE f #-}
f x = case x of
Nothing -> 1#
Just _ -> 2#
main = print (I# (f (Just 4)))
Then, to pattern match on x in the body of f, we don't need to dereference the pointer to the heap and check the constructor info, for we can simply (when x is evaluated) look at its tag.
The above example compiles to the following cmm code with ghc -dno-typeable-binds -fforce-recomp -ddump-opt-cmm -ddump-to-file X.hs:
f_rib_entry() { // [R2]
...
cOo: // global
I64[Sp - 8] = block_cOf_info;
R1 = _sO4::P64;
Sp = Sp - 8;
// Check if tag is 0
if (R1 & 7 != 0) goto cOf; else goto cOg;
cOg: // tag==0 -> evaluate thunk
call (I64[R1])(R1) returns to cOf, args: 8, res: 8, upd: 8;
cOf: // tag/=0 -> pattern match through constructor tag
_sO5::P64 = R1;
_cOl::P64 = _sO5::P64 & 7;
// Check if tag is 1 or 2
if (_cOl::P64 != 1) goto cOk; else goto cOj;
cOk: // Tag is 2, con is Just, return unboxed 2
R1 = 2;
Sp = Sp + 8;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
cOj: // Tag is 1, con is Nothing, return unboxed 1
R1 = 1;
Sp = Sp + 8;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
}
}
The question is what happens when we have more than 7 constructors (the tag can only be in the last 3 bits of the pointer, and 0 means unevaluated data type).
In the case of a datatype with more than 7 constructors, a tag of 7 means that the constructor index is 7 or higher, and therefore we have to dereference the pointer and look at the constructor info. The other tags from 0-6 retain their meaning.
Therefore, the most common constructors of a datatype with >7 constructors are better off being in the first 6 constructors, and the least common should come later. So if you have a datatype of which 80% of the times is constructed with some Con1, it is more performant to have it be one of the first 6.
This could possibly matter in really, REALLY, tight loops 😝, though I would love to see such a case. Or a gigantic code base in which all the useful constructors are defined last.
- Lingua principale
- HTML
- Stelle
- 189
- Fork
- 12
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di haskellfoundation/hs-opt-handbook.github.io
-
Fix the asm lexerApertasphinx
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
haskellfoundation/hs-opt-handbook.github.io#116 · 2 commenti ·
-
Understanding Demand AnalysisForse di nuovo libera @doyougnu l’ha presa 781 giorni fa e non c’è nessuna pull request aperta. Apertaoptimization
haskellfoundation/hs-opt-handbook.github.io#115 · 1 assegnatario ·
-
Split Measurement_Observation into two sections: Measurement, ObservationForse di nuovo libera @doyougnu l’ha presa 793 giorni fa e non c’è nessuna pull request aperta. Apertagood first issue
haskellfoundation/hs-opt-handbook.github.io#114 · 1 assegnatario ·
-
Data-Oriented Design chapterApertaoptimization
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
haskellfoundation/hs-opt-handbook.github.io#112 · 6 commenti ·
Tutte le issue di haskellfoundation/hs-opt-handbook.github.io
Issue simili
-
bot-triaged module: inductor oncall: pt2 topic: fuzzer triaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
bug needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
microsoft/DirectXShaderCompiler#9087 ·
I maintainer di solito rispondono entro 1 giorno
-
confirmed generated by fuzzer llvm:codegen miscompilation
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
llvm/llvm-project#237380 ·
I maintainer di solito rispondono entro 1 giorno
-
Source comments still name the removed set_observer_thresholds and set_observer_scale builtinsApertaarea:observer area:trace-tape found-by:code-review kind:docs-drift
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
InauguralSystems/EigenScript#2212 ·
I maintainer di solito rispondono entro 1 giorno
-
bug medium priority openmp tokenizer wrong result
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno