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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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