Deutsch
Quelltexte/ Codesnippets

1-Bits zählen: Hammingcode-Gewichtung mittels POPCOUNT Algorithmus

 

p.specht

Als Voraussetzung für Codes, die besonders zur Datenübertragung über schlechte oder gestörte Übertragungskanäle geeignet sind (sog. Hamming-Codes, etwa vom Mars-Orbiter zur Erde) ist es wichtig, die Anzahl von ´1´- und ´0´-Bits in einem Datenblock zu kennen. Man benötigt also eine Funktion, die möglichst schnell die Anzahl der '1' in einem Byte, Word, DoubleWord (ab XProfan-X1 auch Quadwords = 8 Byte Integers) ermitteln kann. Da gibt es zahlreiche Tricks und Algorithmen, wie das nachstehende Progi zeigt.
WindowTitle upper$("HAMMING-GEWICHTUNG a.k.a. PopCount( ) der ´1´-bits")
// (D) Demo only, übersetzt 2018-08 by P.Specht, Vienna/EU
// No warranty whatsoever! Ohne jede Garantie! Rechte Dritter ungeprüft!
// Quelle http;//rosettacode.org/wiki/Population_count
// C-Source  https;//en.wikipedia.org/wiki/Hamming_weight
'********************************************************************
var x2&=%11000000000100000100000000000011// <<< CHANGE THIS VALUE
'********************************************************************
CLS:font 2
print "\n TESTWERTE: "
// Limitations test vars:
var x0&=%11111111111111111111111111111111
var x1&=%00000000000000000000000000000000
// Types and constants used in the functions below.
// uint64_t is an unsigned 64-bit integer variable type (in C99 version of C )
// Here (XProfan 11.2a) sInt32 are treated as uInt32
DEF &m1 $55555555//binary 0101...
DEF &m2 $33333333//binary 00110011..
DEF &m4 $0f0f0f0f//binary  4 zeros,  4 ones ...
DEF &m8 $00ff00ff//binary  8 zeros,  8 ones ...
DEF &m16 $0000ffff//binary 16 zeros, 16 ones ...
DEF &m32 $00000000//binary 32 zeros, 32 ones
DEF &hff $ffffffff//binary  all ones
DEF &h01 $01010101//the sum of 256 to the power of 0,1,2,3...
// MAIN
print "\n ";NaivePopCount(x0&),NaivePopCount(x1&),NaivePopCount(x2&)
print "\n ";popcount32a(x0&),popcount32a(x1&),popcount32a(x2&)
print "\n ";popcount32b(x0&),popcount32b(x1&),popcount32b(x2&)
print "\n ";popcount32c(x0&),popcount32c(x1&),popcount32c(x2&)
print "\n ";popcount_d(x0&),popcount_d(x1&),popcount_d(x2&)
print "\n Initializing 65536 Elements of Lookup Table ... (Just a moment, please!)"
Declare Wordbits&[65535]
popcount32e_init
sound 2000,40:locate %csrlin-1,1
print "                 OK.                                                      "
print "\n ";popcount32e(x0&),popcount32e(x1&),popcount32e(x2&)
print "\n\n --- ENDE ---"
waitinput 20000
END//

Proc NaivePopCount :parameters x&

    var n&=x& & 1

    whileloop 31

        x&=x&>>1
        case x& & 1:inc n&

    endwhile

    return n&

endproc

Proc popcount32a :parameters x&

    // Simple implementation, uses 24 arithmetic operations (shift, add, and).
    x&=(x& & &m1)+((x&>>1) & &m1)//put count of each  2 bits into those  2 bits
    x&=(x& & &m2)+((x&>>2) & &m2)//put count of each  4 bits into those  4 bits
    x&=(x& & &m4)+((x&>>4) & &m4)//put count of each  8 bits into those  8 bits
    x&=(x& & &m8)+((x&>>8) & &m8)//put count of each 16 bits into those 16 bits
    x&=(x& & &m16)+((x&>>16) & &m16)//put count of each 32 bits into those 32 bits; End for 32-bit
    'x&=(x& & &m32)+((x&>>32) & &m32) //put count of each 64 bits into those 64 bits
    return x&

EndProc

Proc popcount32b :parameters x&

    //This uses fewer arithmetic operations than any other known
    //implementation on machines with slow multiplication.
    //Algorithm uses 17 arithmetic operations.
    x&=x&-((x&>>1) & &m1)//put count of each 2 bits into those 2 bits
    x&=(x& & &m2)+((x&>>2) & &m2)//put count of each 4 bits into those 4 bits
    x&=(x&+(x&>>4)) & &m4//put count of each 8 bits into those 8 bits
    x&=x&+(x&>>8)//put count of each 16 bits into their lowest 8 bits
    x&=x&+(x&>>16)//put count of each 32 bits into their lowest 8 bits; End of 32-bit
    //  x&=x&+(x&>>32) //put count of each 64 bits into their lowest 8 bits; case 64-bit
    return x& & $7f

EndProc

Proc popcount32c :parameters x&

    //This uses fewer arithmetic operations than any other known
    //implementation on machines with fast multiplication.
    //&his algorithm uses 12 arithmetic operations, one of which is a multiply.
    x&=x&-((x&>>1) & &m1)//put count of each 2 bits into those 2 bits
    x&=(x& & &m2)+((x&>>2) & &m2)//put count of each 4 bits into those 4 bits
    x&=(x&+(x&>>4)) & &m4//put count of each 8 bits into those 8 bits
    return (x&*&h01)>>56//returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...

EndProc

'Die obigen Implementierungen haben das beste Worst-Case-Verhalten aller bekannten Algorithmen.
'Wenn jedoch erwartet wird, dass ein Wert wenige Bits ungleich Null hat, kann es stattdessen
'effizienter sein Algorithmen zu verwenden, die diese Bits einzeln zählen. Wie Wegner [1960]
'beschreibt, unterscheidet sich das bitweise UND von x mit x-1 von x nur durch das Nullsetzen
'des niederwertigsten Bits - Subtrahieren von 1 ändert den rechten String von 0s zu 1s und
'den rechten String von 1 zu 0. Wenn x ursprünglich n Bits hatte, die 1 waren, wird x nach
'nur n Iterationen dieser Operation auf Null reduziert. <Übersetzt mit www.DeepL.com/Translator>

Proc popcount_d :parameters x&//This is better when most bits in x are 0.

    //This is algorithm works the SAME FOR ALL DATA SIZES.
    //It uses 3 arithmetic operations and 1 comparison/branch per %1 in x.
    var count&=0

    While x&

        inc count&
        x&=x& & (x&-1)

    endwhile

    return count&

Endproc

'Wenn uns mehr Speicherplatz zur Verfügung steht, können wir das Hamming-Gewicht schneller
'berechnen als die oben genannten Methoden. Mit unbegrenztem Speicher könnten wir einfach
'eine große Lookup-Tabelle mit dem Hamming-Gewicht jeder 64-Bit-Ganzzahl erstellen.
'Wenn wir eine Lookup-Tabelle der Hamming-Funktion jeder 16-Bit Ganzzahl speichern können,
'können wir folgendes tun, um das Hamming-Gewicht jeder 32-Bit-Ganzzahl zu berechnen:
//Declare Wordbits&[65535]  // bitcounts of integers 0 through 65535

Proc popcount32e_init

    // For filling the wordbits[] table, use the fastest function for your system.

    whileloop 0,$ffff

        wordbits&[&Loop]=popcount_d(&Loop)// if fastest

    Endwhile

Endproc

// Now we simply can do a lookup 2 times

Proc popcount32e :parameters x&

    //This algorithm uses 3 arithmetic operations and 2 memory reads only
    return int(wordbits&[x& & $ffff]+wordbits&[x&>>16])

EndProc

// HINT
// Mula et al. [11] have shown that a vectorized version of popcount64b can run
// faster than dedicated instructions (e.g., popcnt on ×64 processors).
 
XProfan 11
Computer: Gerät, daß es in Mikrosekunden erlaubt, 50.000 Fehler zu machen, zB 'daß' statt 'das'...
28.05.2021  
 



Zum Quelltext


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

1.350 Betrachtungen

Unbenanntvor 0 min.
p.specht21.11.2021
R.Schneider20.11.2021
Uwe Lang20.11.2021
Manfred Barei19.11.2021
Mehr...

Themeninformationen

Dieses Thema hat 1 Teilnehmer:

p.specht (1x)


Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie