Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

popcnt: Wasm-Textanweisung

Die popcnt-Anweisung, kurz für population count, wird verwendet, um die Anzahl der 1en in der binären Darstellung einer Zahl zu zählen.

Probieren Sie es aus

(module

  (func (export "count1s") (param $num i32) (result i32)
    ;; load the number onto the stack
    local.get $num

    ;; count the amount of 1s and return the result
    i32.popcnt
  )

)
const url = "{%wasm-url%}";
await WebAssembly.instantiateStreaming(fetch(url), { console }).then(
  (result) => {
    const count1s = result.instance.exports.count1s;

    console.log(count1s(0b10000010));
    // Expected output: 2
  },
);

Syntax

value_type.popcnt
value_type

Der Werttyp, auf dem die Anweisung ausgeführt wird. Die folgenden Typen unterstützen popcnt:

  • i32
  • i64
  • i8x16 v128 Interpretation
popcnt

Die popcnt-Anweisung. Muss immer nach dem value_type und einem Punkt (.) eingefügt werden.

Typ

[input] -> [output]
input

Der Eingabewert.

output

Der Ausgabewert.

Bei einem nicht-SIMD popcnt sind dies einfache numerische Werte wie 3.

Bei einem SIMD popcnt sind dies v128-Wertinterpretationen, beispielsweise i8x16 0 1 34 12 2 2 2 8 19 20 3 -1 -45 0 0 30. Jede Lane des Outputs, der in den Stapel geschoben wird, enthält die Anzahl der 1en im binären Äquivalent der entsprechenden Lane im Eingabewert.

Binärcodierung

Anweisung Binärformat Beispiel Text => Binär
i32.popcnt 0x69 i32.popcnt => 0x69
i64.popcnt 0x7b i64.popcnt => 0x7b
i8x16.popcnt 0xfd 98:u32 i8x16.popcnt => 0xfd 0x62

Beispiele

Verwendung von SIMD popcnt

In diesem Beispiel demonstrieren wir die Verwendung von popcnt, um die Anzahl der 1en in der binären Darstellung des Lane-Inhalts eines SIMD-Werts zu zählen.

JavaScript

In unserem Skript holen wir uns eine Referenz auf ein <p>-Element, in das wir unser Ergebnis ausgeben werden, und definieren dann ein Objekt für den Import in Wasm, das eine einzelne Funktion enthält, die einen Wert in das <p> ausgibt. Dann kompilieren und instanziieren wir unser Wasm-Modul mit der Methode WebAssembly.instantiateStreaming() und importieren dabei das Objekt.

js
const outputElem = document.querySelector("p");

const obj = {
  output(val) {
    outputElem.textContent += val;
  },
};

WebAssembly.instantiateStreaming(fetch("{%wasm-url%}"), {
  obj,
});

Wasm

In unserem Wasm-Modul importieren wir zuerst die JavaScript-Funktion output(), und stellen sicher, dass sie einen i32-Parameter deklariert. Dann deklarieren wir einen SIMD i8x16-Wert und verwenden i8x16.popcnt, um die binären 1en in all seinen Lanes zu zählen. Schließlich extrahieren wir den in Lane 15 des Output-Werts gespeicherten Wert mit der extract_lane_s Anweisung und geben ihn durch Aufruf der importierten output() Funktion in das DOM aus.

wat
(module
  ;; Import output function
  (import "obj" "output" (func $output (param i32)))

  (func $main
    ;; load a SIMD value onto the stack
    v128.const i8x16 0 1 34 12 2 2 2 8 19 20 3 -1 -45 0 0 30

    i8x16.popcnt ;; count 1s in all the lanes and output as a new i8x16 value
    i8x16.extract_lane_s 15 ;; Extract a value from the result
    call $output
  )

  (start $main)
)

Ergebnis

Die Ausgabe ist wie folgt:

4 wird ausgegeben, weil der Wert in Lane 15 des Eingabewerts 30 ist. 30 in Binär ist 00011110, was 4 1en enthält.