32-разрядный по сравнению с 64-разрядной производительностью с плавающей точкой

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

q = x(0)*y(0)*z(0) + x(1)*y(1)*z(1) + ...

где продолжительность суммирования между 4 и 7.

Исходные вычисления все сделаны с помощью 64-разрядной точности. Для экспериментирования я пытался использовать 32-разрядную точность для x, y, z входные значения (так, чтобы вычисления были выполнены с помощью 32-разрядного), и храня конечный результат как 64-разрядное значение (простой бросок).

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

Рассматриваемой архитектурой является Intel 64, Linux и GCC. И коды, действительно кажется, используют SSE и массивы, в обоих случаях выровненные к 16-байтовой границе.

Почему это было бы так? Мой думаю так далекий то, что 32-разрядная точность может использовать SSE только на первых четырех элементах, при этом остальные сделан последовательно составленный броском наверху.

8
задан Peter Mortensen 12 April 2013 в 20:17
поделиться

3 ответа

По крайней мере, на x87 все действительно внутренне выполняется с 80-битной точностью. На самом деле точность просто определяет, сколько из этих битов хранится в памяти. Это одна из причин, по которой различные настройки оптимизации могут незначительно изменить результаты: они изменяют величину округления с 80-битной на 32- или 64-битную.

На практике использование 80-битных чисел с плавающей запятой ( long double в C и C ++, real в D) обычно выполняется медленно, поскольку нет эффективного способа загрузки и хранения 80 бит. из памяти. 32- и 64-разрядные версии обычно работают одинаково быстро при условии, что пропускная способность памяти не является узким местом, т.е. если все равно все находится в кеше. 64-разрядная версия может работать медленнее, если произойдет одно из следующих событий:

  1. Пропускная способность памяти является узким местом.
  2. 64-битные числа неправильно выровнены по 8-байтовым границам. 32-битные числа требуют только 4-байтового выравнивания для оптимальной эффективности, поэтому они менее привередливы. Некоторые компиляторы (на ум приходит компилятор Digital Mars D) не всегда делают это правильно для 64-битных двойников, хранящихся в стеке. Это приводит к тому, что для загрузки одной из них требуется вдвое больше операций с памятью, что на практике приводит примерно к двукратному снижению производительности по сравнению с правильно выровненными 64-битными или 32-битными числами с плавающей запятой.

Что касается оптимизации SIMD, следует отметить, что большинство компиляторов ужасно плохо справляются с автоматической векторизацией кода. Если вы не хотите писать напрямую на языке ассемблера, лучший способ воспользоваться этими инструкциями - использовать такие вещи, как операции с массивами, которые доступны, например, в D и реализованы в терминах инструкций SSE. Точно так же в C или C ++ вы, вероятно, захотите использовать высокоуровневую библиотеку функций, оптимизированных для SSE, хотя я не знаю хорошей из них, потому что я в основном программирую на D.

24
ответ дан 5 December 2019 в 06:52
поделиться

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

0
ответ дан 5 December 2019 в 06:52
поделиться

Сначала проверьте созданный ASM.Это может быть не то, что вы ожидаете.

Также попробуйте записать его в виде цикла:

typedef float fp;
fp q = 0
for(int i = 0; i < N; i++)
  q += x[i]*y[i]*z[i]

Некоторые компиляторы могут заметить цикл, а не развернутую форму.

Наконец, ваш код использовал () , а не []. Если ваш код выполняет много вызовов функций (от 12 до 21), это приведет к потере стоимости FP, и даже удаление вычисления fp не будет иметь большого значения. Встраивание OTOH может.

0
ответ дан 5 December 2019 в 06:52
поделиться
Другие вопросы по тегам:

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