Вывести тест, вставленный оптимизатором, из циклаC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Вывести тест, вставленный оптимизатором, из цикла

Сообщение Anonymous »

Оптимизатор Clang вводит тест во время выполнения для выбора инструкций в плотный цикл. Как я могу сообщить ему, что проверяемое условие не является необходимым?
Подробнее
Вот функция, определяющая, имеет ли число простые множители.

Код: Выделить всё

#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();
}
С помощью Compiler Explorer я убедился, что частное и остаток вычисляются с помощью одного DIV.
Код, сгенерированный MSVC, всегда использует 64-битный DIV. Код clang выбирает между 32- и 64-битным DIV в зависимости от того, умещаются ли кандидат и простое в 32 бита.
  • Когда деление можно выполнить с помощью 32 бит, код MSVC будет медленнее, чем код Clang.
  • Когда необходимо использовать 64 бита, код Clang будет медленнее (из-за тестов в цикл).
Обратите внимание, что если кандидат умещается в 32 бита, то все простые делители также будут умещаться. Поэтому я хотел бы вывести выбор инструкций из цикла.
Решение для 32-битных значений
Мне удалось заставить оба компилятора оптимизировать 32-битный путь следующим образом:

Код: Выделить всё

#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 

Подробнее здесь: [url]https://stackoverflow.com/questions/79846716/hoist-an-optimizer-inserted-test-out-of-a-loop[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»