Heben Sie einen vom Optimierer eingefügten Test aus einer SchleifeC++

Programme in C++. Entwicklerforum
Anonymous
 Heben Sie einen vom Optimierer eingefügten Test aus einer Schleife

Post by Anonymous »

Clangs Optimierer fügt einen Laufzeittest für die Befehlsauswahl in eine enge Schleife ein. Wie kann ich ihm mitteilen, dass die von ihm überprüfte Bedingung unnötig ist?
Details
Hier ist eine Funktion, um zu bestimmen, ob eine Zahl Primfaktoren hat.

Code: Select all

#include 
#include 
#include 

using number_t = std::uintmax_t;
std::vector primes;  // initialized elsewhere

bool factorable(number_t candidate) {
for (auto const prime : primes) {
auto const quotient  = candidate / prime;
auto const remainder = candidate % prime;
if (quotient < prime) return false;
if (remainder == 0) return true;
}
std::unreachable();
}
Mit Compiler Explorer habe ich überprüft, dass Quotient und Rest mit einem einzelnen DIV berechnet werden.
Der von MSVC generierte Code verwendet immer 64-Bit-DIV. Der Clang-Code wählt zwischen 32- und 64-Bit-DIV aus, basierend darauf, ob Kandidat und Primzahl beide in 32 Bit passen.
  • Wenn die Divisionen mit 32 Bit durchgeführt werden können, ist der MSVC-Code langsamer als der Clang-Code.
  • Wenn sie 64 Bit verwenden müssen, ist der Clang-Code langsamer (aufgrund von Tests in Schleife).
Beachten Sie, dass, wenn Kandidat in 32-Bit passt, auch alle Primzahlteiler passen. Daher möchte ich die Befehlsauswahl aus der Schleife herausholen.
Lösung für 32-Bit-Werte
Ich konnte beide Compiler wie folgt dazu bringen, für den 32-Bit-Pfad zu optimieren:

Code: Select all

#include 
#include 
#include 
#include 
#include 

using number_t = std::uintmax_t;
std::vector primes;  // initialized elsewhere

template 
bool factorableT(T candidate) {
for (auto const prime : primes) {
auto const prime_as_T = static_cast(prime);
auto const quotient  = candidate / prime_as_T;
auto const remainder = candidate % prime_as_T;
if (prime > quotient) return false;
if (remainder == 0) return true;
}
std::unreachable();
}

bool factorable(number_t candidate) {
if constexpr (sizeof(candidate) > sizeof(std::uint32_t)) {
if (candidate

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post