Skip to content

GCC C-Vektorerweiterung: Wie kann man überprüfen, ob das Ergebnis eines elementweisen Vergleichs wahr ist und welche?

Lösung:

Die Vektorerweiterung von Clang leistet gute Arbeit mit dem any Funktion.

#if defined(__clang__)
typedef int64_t vli __attribute__ ((ext_vector_type(VLI_SIZE)));
typedef double  vdf __attribute__ ((ext_vector_type(VDF_SIZE)));
#else
typedef int32_t vsi __attribute__ ((vector_size (SIMD_SIZE)));
typedef int64_t vli __attribute__ ((vector_size (SIMD_SIZE)));
#endif

static bool any(vli const & x) {
  for(int i=0; i<VLI_SIZE; i++) if(x[i]) return true;
  return false;
}

Montage

any(long __vector(4) const&): # @any(long __vector(4) const&)
  vmovdqa ymm0, ymmword ptr [rdi]
  vptest ymm0, ymm0
  setne al
  vzeroupper
  ret

Obwohl pmovmskb ist vielleicht immer noch die bessere wahl ptest ist immer noch eine enorme Verbesserung gegenüber dem, was GCC tut

any(long __vector(4) const&):
  cmp QWORD PTR [rdi], 0
  jne .L5
  cmp QWORD PTR [rdi+8], 0
  jne .L5
  cmp QWORD PTR [rdi+16], 0
  jne .L5
  cmp QWORD PTR [rdi+24], 0
  setne al
  ret
.L5:
  mov eax, 1
  ret

GCC sollte dies beheben. Clang ist jedoch nicht optimal für AVX512.

Die any Funktion Ich würde argumentieren, dass es sich um eine kritische Vektorfunktion handelt, daher sollten Compiler entweder ein eingebautes Element bereitstellen, wie sie es für Shuffle tun (zB __builtin_shuffle für GCC und __builtin_shufflevector für clang) oder der Compiler sollte schlau genug sein, um den optimalen Code herauszufinden, wie es Clang zumindest für SSE und AVX tut, aber nicht für AVX512.

Click to rate this post!
[Total: 0 Average: 0]



Anderer Beitrag

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.