Вычисления с фиксированной точкой будут стоить моей проблемы?

Я работаю над гидроаэродинамикой, Navier - Топит решатель, который должен работать в режиме реального времени. Следовательно, производительность важна.

Прямо сейчас я смотрю на многие жесткие циклы что каждый счет на значительную часть времени выполнения: нет никакого единственного узкого места. Большинство этих циклов делает некоторую арифметику с плавающей точкой, но существует большое ветвление промежуточного.

Операции с плавающей точкой главным образом ограничены дополнениями, вычитаниями, умножением, подразделениями и сравнениями. Все это сделано с помощью 32-разрядных плаваний. Моя целевая платформа является x86, по крайней мере, с инструкциями SSE1. (Я проверил в ассемблерном выводе, что компилятор действительно генерирует инструкции SSE.)

Большинство значений с плавающей точкой, с которыми я работаю, имеет довольно небольшую верхнюю границу, и точность для почти нулевых значений не очень важна. Таким образом, мысль произошла со мной: возможно, переключение на вычисления с фиксированной точкой могло ускорить вещи? Я знаю, что единственный способ быть действительно уверенным состоит в том, чтобы измерить его, который мог бы занять дни, таким образом, я хотел бы знать разногласия успеха заранее.

Фиксированная точка была всем гневом назад в эпоху Гибели, но я не уверен, где это стоит anno 2010. Рассмотрение, сколько кремния в наше время накачано в производительность с плавающей точкой, является там шансом, что вычисления с фиксированной точкой все еще дадут мне значительное повышение скорости? У кого-либо есть реальный опыт, который может относиться к моей ситуации?

12
задан Thomas 19 April 2010 в 12:38
поделиться

3 ответа

Как говорили другие, если вы уже используете SIMD с плавающей запятой, я сомневаюсь, что вы добьетесь значительных улучшений с фиксированной запятой.

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

Две другие области, на которые следует обратить внимание:

  1. Доступ к памяти - если все ваши вычисления выполняются в SSE, то промахи в кэше могут занимать больше времени, чем фактические вычисления.

    1. Вы можете предварительно загрузить данные, например, _mm_prefetch или __builtin_prefetch (в зависимости от вашего компилятора / платформы).
    2. Проверьте дорогостоящие функции на наличие наложения имен между входами и выходами; это может привести к дополнительному чтению / записи в память.
    3. Рассмотрите возможность хранения ваших данных по-другому - если ваш жидкостный решатель решает координаты x независимо от y, было бы удобнее хранить их в разных массивах. Если они решаются вместе, рассмотрите возможность чередования (например, x y x y ...)
  2. Разворачивание - вы сможете получить выигрыш в производительности от разворачивания ваших внутренних циклов. Цель не в том (как думают многие) в том, чтобы уменьшить количество проверок завершения цикла.Основное преимущество - это возможность чередования независимых инструкций, чтобы скрыть задержку инструкций. Там есть презентация здесь под названием Оптимизация VMX: повышение уровня , которая может немного помочь; он сосредоточен на инструкциях Altivec для Xbox360, но некоторые из развернутых советов могут помочь и в SSE.

Как уже упоминали другие люди, профиль, профиль, профиль. А затем дайте нам знать, что все еще медленное :)

PS - в одном из ваших постов здесь я убедил вас использовать SOR вместо Gauss-Seidel в вашем решателе матриц. Теперь, когда я думаю об этом, есть ли причина, по которой вы не используете трехдиагональный решатель?

3
ответ дан 2 December 2019 в 22:37
поделиться

Ваша машина довольно хорошо оптимизирована для работы с числами с плавающей запятой, поэтому вы, вероятно, не сильно сэкономите, перейдя к дробям с фиксированной запятой.

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

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

0
ответ дан 2 December 2019 в 22:37
поделиться

Используйте плавающую точку. Фиксированная точка действительно полезна только в том случае, если вы можете работать с 8 или 16 битами и использовать SIMD (обработка изображений и аудио являются типичными вариантами использования для этого).

Современные процессоры обычно имеют 2 FPU, и вы можете выполнять до 2 инструкций FP за такт. Затем у вас также есть возможность оптимизации с использованием 4-сторонней FP SIMD (SSE).

Если вы все еще не можете добиться хорошей производительности, попробуйте использовать лучший компилятор, например, Intel ICC. Кроме того, 64-битные исполняемые файлы Intel, как правило, несколько быстрее своих 32-битных аналогов из-за увеличенного количества регистров в 64-битной модели, поэтому, если можете, создавайте 64-битные.

И, конечно же, вы должны профилировать свой код, чтобы точно знать, где находятся точки доступа. Вы не говорите, какую ОС вы используете, но VTune в Windows, Zoom в Linux или Shark в Mac OS X - все это поможет вам быстро и легко найти узкие места в производительности.

6
ответ дан 2 December 2019 в 22:37
поделиться
Другие вопросы по тегам:

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