Будет ли арифметика с фиксированной точкой стоить моей проблемы? - PullRequest
12 голосов
/ 19 апреля 2010

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

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

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

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

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

Ответы [ 3 ]

6 голосов
/ 19 апреля 2010

Палка с плавающей точкой. Фиксированная точка действительно полезна только в том случае, если вы можете работать в пределах 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 помогут вам быстро и легко найти узкие места в вашей работе.

3 голосов
/ 20 апреля 2010

Как уже говорили другие люди, если вы уже используете 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 в вашем матричном решателе. Теперь, когда я думаю об этом, есть ли причина, по которой вы не используете трехдиагональный решатель?

0 голосов
/ 19 апреля 2010

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

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

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

...