Необычный быстрый обратный квадратный корень John Carmack (Quake III)

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

105
задан David Foerster 12 July 2015 в 23:17
поделиться

3 ответа

К вашему сведению. Кармак этого не писал. Терье Матисен и Гэри Таролли частично (и весьма скромно) признают это, а также ссылаются на некоторые другие источники.

Как была получена мифическая константа, остается загадкой.

Цитата Гэри Таролли:

] Что на самом деле делает плавающий вычисление точки в целых числах - потребовалось долго разбираться как и почему это работает, и я не могу вспомнить

Немного лучшая константа , разработанная опытным математиком (Крис Ломонт), пытающимся выяснить, как работал исходный алгоритм, выглядит следующим образом:

float InvSqrt(float x)
{
    float xhalf = 0.5f * x;
    int i = *(int*)&x;              // get bits for floating value
    i = 0x5f375a86 - (i >> 1);      // gives initial guess y0
    x = *(float*)&i;                // convert bits back to float
    x = x * (1.5f - xhalf * x * x); // Newton step, repeating increases accuracy
    return x;
}

Несмотря на это, его первоначальная попытка математически «Улучшенная» версия id sqrt (которая пришла к почти той же константе) оказалась хуже той, которая была изначально разработана Гэри, несмотря на то, что математически была намного «чище». Он не мог объяснить, почему id был таким превосходным iirc.

70
ответ дан 24 November 2019 в 04:00
поделиться

Конечно, в наши дни это оказывается намного медленнее, чем просто использование sqrt FPU (особенно на 360 / PS3), потому что переключение между регистрами float и int приводит к загрузке и попаданию в хранилище. , в то время как модуль с плавающей запятой может делать обратный квадратный корень аппаратно.

Это просто показывает, как должна развиваться оптимизация по мере изменения характера лежащего в основе оборудования.

51
ответ дан 24 November 2019 в 04:00
поделиться

В вашей трассировке есть все вставки длительностью 0–3 мс. Между выполнениями бывает гораздо больше времени : вставка заканчивается в 12:53:10, следующая начинается в 12:53:13, поэтому в клиенте задержка составляет 3 секунды. ] между двумя вставками. Технически задержка может быть где угодно между клиентом и сервером, но по описанным вами симптомам я бы исключил случайный нестабильный маршрутизатор между клиентом и сервером (поведение было бы более случайным).

Кое-где я бы посмотрел:

  • события роста базы данных / событие роста журнала. Это очень часто встречается с тестами, потому что тестовая установка развертывает совершенно новую тестовую базу данных, а затем тест достигает события роста примерно в тот же момент (скажем, 10-я вставка). Можно легко проверить с помощью счетчиков производительности и событий профилировщика: Класс события автоматического увеличения файла данных . Решение состоит в том, чтобы предварительно вырастить тестовую базу данных (на самом деле вы всегда должны предварительно наращивать и mdf, и ldf для тестирования производительности). Однако не учитывает геометрическую скорость увеличения времени.
  • Сборщик мусора в клиенте. Опять же, это можно отследить по счетчикам производительности.
  • Исчерпание пула соединений (т. Е. При тестировании происходит утечка соединений, пул должен открывать новые и настроен на поддержание минимального счетчика, поэтому он открывается партиями). sys.dm_exec_connecitons будет расти. Также есть счетчик perfmon для пользовательских сессий (как на сервере, так и на счетчиках ADO.Net).
  • дефект кода. Некоторое ожидание / обработка в клиентском коде, возможно, обработка списка. Это наиболее вероятная причина, единственная, которая объясняет квадратную скорость увеличения задержки (NxN для списка длиной N, N увеличивается с каждым запуском теста, возможно, сортировка, не могу следить за ним, выделяется как i = 0x5f3759df - (i >> 1); линия. Упрощенный, Ньютон-Рафсон - приближение это начинается с предположения и уточняет его с итерацией. Принимая преимущество природы 32-битной x86 процессоров, i, целое число, изначально установлено значение число с плавающей запятой, которое вы хотите взять обратный квадрат, используя целочисленное приведение. i тогда устанавливается на 0x5f3759df, минус сам сдвинул единицу немного вправо. Правый сдвиг отбрасывает младший бит i, фактически уменьшив его вдвое.

    Это действительно хорошее чтение. Это лишь малая часть.

21
ответ дан 24 November 2019 в 04:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: