Подтвердить что ты не робот

C/С++ - самая быстрая работа в журнале cmath

Я пытаюсь вычислить log a b (и получить обратно с плавающей точкой, а не целое число). Я планировал сделать это как log(b)/log(a). Математически я могу использовать любую из cmath лог-функций (основание 2, e или 10) для выполнения этого расчета; Тем не менее, я буду использовать этот расчет во время моей программы, поэтому мне было интересно, если один из них значительно быстрее других (или еще лучше, если есть более быстрый, но все же простой способ сделать это). Если это имеет значение, то и a, и b являются целыми числами.

4b9b3361

Ответ 1

Так как b и a являются целыми числами, вы можете использовать всю славу бит twiddling, чтобы найти их журналы на базе 2. Вот некоторые из них:

  • Найти базу данных 2 целого числа с MSB N, установленным в операциях O (N) (очевидным образом)
  • Найдите целочисленную базу данных 2 целого числа с 64-битным плавающим IEEE
  • Найти базу данных 2 целого числа с помощью таблицы поиска
  • Найдите базу данных 2 целочисленного N-бита в операциях O (lg (N))
  • Найти базу данных 2 из N-разрядного целого числа в операциях O (lg (N)) с умножением и поиском

Я оставлю это вам, чтобы выбрать наилучшую функцию быстрого доступа для ваших нужд.

Ответ 2

Сначала просчитайте 1.0/log(a) и умножьте каждый log(b) на это выражение.

Изменить: Я изначально сказал, что естественный логарифм (база e) будет самым быстрым, но другие утверждают, что база 2 поддерживается непосредственно процессором и будет самой быстрой. У меня нет причин сомневаться в этом.

Изменить 2: Я предполагал, что a был константой, но в повторном чтении вопроса, который никогда не был указан. Если это так, то нет никакой выгоды для предварительного расчета. Однако, если вы можете сохранить читаемость с соответствующим выбором имен переменных:

const double base_a = 1.0 / log(a);
for (int b = 0; b < bazillions; ++b)
    double result = log(b) * base_a;

Как ни странно Microsoft не предоставляет базовую функцию журнала, которая объясняет, почему я не знаком с ней. Кроме того, инструкция x86 для вычисления журналов включает в себя автоматическое умножение, а константы, необходимые для разных баз, также доступны через оптимизированная команда, поэтому я ожидал бы, что три разные функции журнала будут иметь одинаковые сроки (даже базовая 2 должна умножаться на 1).

Ответ 3

На платформах, для которых у меня есть данные, log2 очень немного быстрее, чем другие, в соответствии с моими ожиданиями. Обратите внимание, однако, что разница крайне незначительная (всего пара процентов). Это действительно не стоит беспокоиться.

Напишите отчет о реализации. Затем измерьте производительность.

Ответ 4

В наборе инструкций 8087 есть только инструкция для логарифма на базу 2, поэтому я предполагаю, что это будет самым быстрым.

Конечно, этот вопрос во многом зависит от вашего процессора/архитектуры, поэтому я предлагаю сделать простой тест и время его.

Ответ 5

Ответ:

  • это зависит
  • профиль

Вы даже не упоминаете свой тип процессора, тип переменной, флаги компилятора, расположение данных. Если вам нужно сделать много из них параллельно, я уверен, что будет опция SIMD. Ваш компилятор оптимизирует это, если вы используете выравнивание и очищаете простые циклы (или valarray, если вам нравятся архаичные подходы).

Скорее всего, у компилятора Intel есть специальные трюки для процессоров Intel в этой области.

Если вы действительно хотели, вы могли бы использовать CUDA и использовать GPU.

Я полагаю, если вам не хватает таких наборов инструкций вы можете опуститься на уровне битбординга и написать алгоритм, который имеет хорошее приближение. В этом случае я могу поставить более одного яблочного пирога, чтобы 2-журнал был быстрее, чем любой другой базовый журнал