3

Я оптимизирую матричную числовую точку доступа.Может ли доступ к неинициализированным значениям привести к результату?

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

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

Я не делаю пилинг по нескольким причинам:

  • лени
  • производительности удара из-за очень плохую местность пилинга пограничного случая.
  • Чтобы избежать сложного кода обрыва границы.

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

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

+1

+1, я настоятельно рекомендую вам по крайней мере нуль инициализировать их. Предполагая, что вы работаете с плавающей точкой, неинициализированные данные имеют высокую вероятность денормализации. [И вы не хотите, чтобы это испортило вашу производительность] (http://stackoverflow.com/questions/9314534/why-does-changing-0-1f-to-0-slow-down-performance-by-10x/ 9314926 # 9314926). – Mysticial

+0

Я знаю, но жадно обнуление пула предварительно выделенных матриц с 'memset' тоже очень дорого. –

+1

Хотя в зависимости от того, насколько велики ваши петли, штраф в несколько сотен циклов в конце каждого цикла, вероятно, не заметен. – Mysticial

ответ

5

Просто чтобы получить педантичный материал из пути:

Согласно стандарту, плохие вещи могут произойти, если вы используете неинициализированные данные. (Стандарт допускает значения «ловушки», которые могут вызывать исключения.) Но для всех практических целей это, вероятно, не применимо здесь.


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

Для чисел с плавающей точкой, существуют две проблемы:

  1. Signalling NaNs
  2. Denormalized Values

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

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

And you really don't want to be messing with denormalized floating-point.

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

Сказанное так: Почему неинициализированные данные подвержены денормализации? Если первые несколько бит значения с плавающей запятой равны нулю, то они денормализуются. Это так просто. Если данные были целыми числами или 64-битным указателем ... Он будет денормализован при интерпретации как значение с плавающей запятой.


Предложения:

  • Нулевой инициализировать данные. Если это слишком дорого, по крайней мере, нуль-инициализировать конечные точки.
  • Избегайте доступа к неинициализированным данным, вставляя этот код очистки. Возможно, что-то вроде Duff's Device. Хотя я обычно предпочитаю набор двоичных сокращающих if-утверждений.
+0

Отличный ответ! Спасибо :) –

Смежные вопросы