Der folgende Code ruft die integrierten Funktionen für clz/ctz in GCC auf und hat auf anderen Systemen C-Versionen. Offensichtlich sind die C-Versionen ein bisschen suboptimal, wenn das System eine eingebaute clz/ctz-Anweisung hat, wie x86 und ARM.Wie benutzt man MSVC-Intrinsics, um das Äquivalent dieses GCC-Codes zu erhalten?
#ifdef __GNUC__
#define clz(x) __builtin_clz(x)
#define ctz(x) __builtin_ctz(x)
#else
static uint32_t ALWAYS_INLINE popcnt(uint32_t x)
{
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return x & 0x0000003f;
}
static uint32_t ALWAYS_INLINE clz(uint32_t x)
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return 32 - popcnt(x);
}
static uint32_t ALWAYS_INLINE ctz(uint32_t x)
{
return popcnt((x & -x) - 1);
}
#endif
Welche Funktionen muss ich anrufen, die Header muss ich schließen, etc hier eine richtige ifdef für MSVC hinzufügen? Ich habe mir schon this page angesehen, aber ich bin mir nicht ganz sicher, wofür das #pragma ist (ist es erforderlich?) Und welche Einschränkungen es den MSVC-Versionsanforderungen für die Kompilierung auferlegt. Als jemand, der MSVC nicht wirklich benutzt, weiß ich auch nicht, ob diese intrinsischen Elemente C-Äquivalente auf anderen Architekturen haben, oder ob ich #ifdef x86/x86_64 auch verwenden muss, wenn ich # definiere.
Die Seite, die Sie oben verweisen bezieht sich auf eine Funktion, die Teil der .NET-Laufzeit ist, versuchen Sie Ihr Programm für .NET oder als native ausführbare Windows-Datei zu erstellen ? –
Es ist eine native Windows-ausführbare Datei - ein Grund dafür ist, dass ich es ziemlich schwierig finde, Microsoft-Dokumentationsseiten zu finden, die heutzutage tatsächlich über C sprechen. –
Libcxx-Implementierung https://github.com/llvm-mirror/libcxx/blob/9dcbb46826fd4d29b1485f25e8986d36019a6dca/include/support/win32/support.h#L106-L182 – KindDragon