Die Indizes von Nicht-Null-Bytes eines SSE / AVX-Registers

Wenn der Wert eines SSE / AVX-Registers so ist, dass alle seine Bytes entweder 0 oder 1 sind, gibt es eine Möglichkeit, die Indizes aller Nicht-Null-Elemente effizient abzurufen?

Zum Beispiel, wenn der xmm-Wert | ist r0 = 0 | r1 = 1 | r2 = 0 | r3 = 1 | r4 = 0 | r5 = 1 | r6 = 0 | ... | r14 = 0 | r15 = 1 | das Ergebnis sollte ungefähr so lauten (1, 3, 5, ..., 15). Das Ergebnis sollte in eine andere _m128i-Variable oder ein anderes char [16] -Array gestellt werden.

Wenn es hilft, können wir davon ausgehen, dass der Wert des Registers so ist, dass alle Bytes entweder 0 oder ein konstanter Wert ungleich Null sind (nicht erforderlich 1).

Ich frage mich ziemlich genau, ob es eine Anweisung dafür gibt oder vorzugsweise C / C ++ intrinsic. In jedem SSE- oder AVX-Befehlssatz.

EDIT 1:

Es war richtigbeobachtet von @ zx485 Diese ursprüngliche Frage war nicht klar genug. Ich habe nach einer "aufeinanderfolgenden" Lösung gesucht.

Das Beispiel0 1 0 1 0 1 0 1... oben sollte eine der folgenden Folgen haben:

Wenn wir annehmen, dass Indizes bei 1 beginnen, dann0 wäre ein Beendigungsbyte und das Ergebnis könnte @ se

002 004 006 008 010 012 014 016 000 000 000 000 000 000 000

Wenn wir annehmen, dass das negative Byte ein Abschlussbyte ist, könnte das Ergebnis @ sei

001 003 005 007 009 011 013 015 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF

Alles, das als aufeinanderfolgende Bytes gibt, die wir als Indizes von Nicht-Null-Elementen im ursprünglichen Wert interpretieren können

EDIT 2:

Indeed, as@ harold und@ Peter Cordes Schlagen Sie in den Kommentaren zum ursprünglichen Beitrag vor, dass eine der möglichen Lösungen darin besteht, zuerst eine Maske zu erstellen (z. B. mitpmovmskb) und dort Indizes ungleich Null prüfen. Das führt aber zu einer Schleife.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage