Fragen? Antworten! Siehe auch: Alternativlos
Das Mem, dass die PSHUFB-Lösung schneller sei als POPCNT, geht schon länger rum, stimmt allerdings nicht, wenn man's richtig macht. :)Wieder was gelernt! :-) (Danke, Fabian)Dan Luu hat darüber geschrieben, das verlinke ich einfach mal:
http://danluu.com/assembly-intrinsics/Das POPCNT-Erratum, dass er da am Ende nennt, existiert über mehrere CPU-Generationen von Intel und ist möglicherweise "Absicht". Nicht um die Performance von POPCNT für nicht-NSA-User zu sabotieren :), sondern weil ein x86-Decoder ziemlich haarig ist und der Bug nicht wirklich schlimm.
Die meisten x86-Befehle sind ja bekanntlich dest = dest OP src. Jedes "Loch" in der Opcode map, in dem ein unärer Befehl steht, muss in der Instruction Decoding-Logik kodiert werden, damit der Renamer weiss, dass der Destination-Operand keine Quelle ist. Nun ist x86 sowieso relativ unregelmäßig, allerdings bei weitem nicht so sehr (auf Encoding-Ebene und für die häufig vorkommenden Befehle), wie viele das denken.
Ursprünglich (bei Nehalem, dem original-Core-i7) war das ziemlich sicher ein Bug, den sie zu spät bemerkt haben: da hat jemand den Spezialfall vergessen und es macht halt nichts wirklich kaputt, also haben sie das Design lieber nicht angefasst. CPU-Hersteller sind bei sowas sehr konservativ: wenn man spät einen nicht-kritischen Bug mit einfachem Workaround findet, dann fixt man den in der Regel nicht. Denn bei dem Bug weiss man, was passiert - ein Fix macht möglicherweise was anderes kaputt, und Validierungszeit und neue Steppings sind extrem teuer. Wenn da was schief geht, hat man erstaunlich schnell zweistellige Millionenbeträge verbrannt, dementsprechend vorsichtig geht man da vor.
In diesem Fall ist der Bug insgesamt harmlos genug, dass er offenbar über mehrere Generationen in der Bug-Datenbank lag und nie gefixt wurde, weil er nicht genug Priorität hatte. Sowas ist nicht selten.
Popcount ist übrigens für diverse SIMD-Anwendungen hilfreich, nicht nur Video. Eigentlich, wann immer es um "filter"-artige Transformationen geht (nicht Filter im DSP-Sinne, sondern die Funktion höherer Ordnung). Bei x86 macht man eine Vergleichsoperation, dann movmskps (oder pmovmskb) um eine Bitmaske mit den Resultaten in ein Integer-Register zu kriegen, und dann kann man mit ein wenig rumgeshuffle die Daten rausschreiben. Popcount braucht man dann am Ende, um rauszufinden, um wieviele Bytes man den Output-Zeiger verschieben soll. Auch da habe ich einen Link: https://deplinenoise.files.wordpress.com/2015/03/gdc2015_afredriksson_simd.pdf
Für SSE2 und 32-bit-Daten ist POPCNT noch ein bisschen albern (eine 16-Element-Tabelle tuts auch), wenn man auf 8-bit oder 16-bit arbeitet oder AVX macht (8 Lanes statt 4) lohnt sichs aber langsam.