gsl_complex vs. std :: комплексная производительность

Я пишу программу, которая во многом зависит от сложных сложений и умножений. Я хотел знать, должен ли я использовать gsl_complex или же std::complex,

Кажется, я не вижу в Интернете сравнения того, насколько лучше сложная арифметика GSL по сравнению с std::complex, Элементарный поиск в Google также не помог мне найти страницу тестов для комплекса GSL.

Я написал программу из 20 строк, которая генерирует два случайных массива комплексных чисел (1e7 из них), а затем проверил, сколько времени заняло сложение и умножение, используя clock() от <ctime>, Используя этот метод (без оптимизации компилятора), я узнал, что gsl_complex_add а также gsl_complex_mul почти в два раза быстрее std::complex<double>«s + а также * соответственно. Но я никогда раньше такого не делал, так что вы проверяете, что быстрее?

Любые ссылки или предложения будут полезны. Спасибо!

РЕДАКТИРОВАТЬ:

Итак, я попробовал еще раз с флагом -O3, и теперь результаты чрезвычайно разные! std::complex<float>::operator+ более чем в два раза быстрее gsl_complex_add, в то время как gsl_complex_mul примерно в 1,25 раза быстрее std::complex<float>::operator*, Если я использую двойной, gsl_complex_add примерно на 30% быстрее, чем std::complex<double>::operator+ в то время как std::complex<double>::operator* примерно на 10% быстрее, чем gsl_complex_mul, Мне нужна только точность на уровне поплавка, но я услышанным этот дубль быстрее (и память не проблема для меня)! Так что теперь я действительно запутался!

1

Решение

Включите оптимизацию.

Любая библиотека или набор функций, с которыми вы связываетесь, будут скомпилированы С оптимизация (если имена разработчиков не включают Кермита, Шведского шеф-повара, Мисс Пегги (менеджер проекта) и Cookie Monster (тестер) — иными словами, команда разработчиков — это группа Muppets).

поскольку std::complex использует шаблоны, он компилируется заданными вами параметрами компилятора, поэтому код будет неоптимизирован. Итак, ваш вопрос на самом деле «Почему функция X быстрее, чем функция Y, которая делает то же самое, когда функция X компилируется с оптимизацией, а Y компилируется без оптимизации?» — что должно быть очевидно, чтобы ответить: «Оптимизация работает почти все время!» (Если бы оптимизация не работала большую часть времени, разработчикам компиляторов было бы НАМНОГО проще)

Изменить: Таким образом, мой вышеупомянутый пункт только что доказан. Обратите внимание, что, поскольку шаблоны могут встроить код, он часто более эффективен, чем внешняя библиотека (потому что компилятор может просто вставить инструкции прямо в поток, а не вызывать другую функцию).

Относительно float против doubleединственный раз, когда float медленнее, чем double если есть ТОЛЬКО double доступно аппаратное обеспечение, с двумя функциями, добавляемыми для «сокращения» и «удлинения» между float а также double, Я не знаю ни о каком таком оборудовании. double имеет больше битов, так что ДОЛЖНО занять больше времени.

Edit2:

Когда дело доходит до выбора «одного решения над другим», существует очень много факторов. Производительность одна (а в некоторых случаях самая важная, в других — нет). Другими аспектами являются «простота использования», «доступность», «пригодность для проекта» и т. Д.

Если вы посмотрите ТОЛЬКО на производительность, вы можете иногда запускать простые тесты производительности, чтобы определить, что одно решение лучше или хуже другого, но для сложных библиотек [не «реально».&мнимые «типа комплексных чисел, а скорее« сложных »], иногда бывают оптимизации для работы с большими объемами данных, где, если вы используете менее сложное решение,« большие данные »не достигнут той же производительности, потому что меньше усилий потрачено на решение проблем типа «большие данные». Итак, если у вас есть «простой» эталонный тест, который выполняет некоторые базовые вычисления для небольшого набора данных, и вы, в действительности, собираетесь запускать гораздо большие наборы данных, Небольшой эталон МОЖЕТ не отражать реальность.

И я ни кто-либо другой не могу сказать вам, какое решение даст вам наилучшую производительность в вашей системе с вашими наборами данных, если только у нас нет доступа к вашим наборам данных, мы точно не знаем, какие вычисления вы выполняете (то есть довольно у вас есть код) и опыт работы с обоими «пакетами».

И если перейти к остальным критериям («простота использования» и т. Д.), Они основаны на «личном мнении», поэтому в первую очередь не подойдут для SO.

4

Другие решения

Этот ответ зависит не только от флагов оптимизации, но также от компилятора, используемого для компиляции библиотеки GSL и вашего конкретного кода. Пример: если вы компилируете gsl с помощью gcc, а вашу программу — с помощью icc, то вы можете увидеть (существенную) разницу (я сделал этот тест с помощью std :: pow vs gsl_pow). Кроме того, стандартный make-файл, сгенерированный ./configure не компилирует GSL с агрессивной оптимизацией с плавающей запятой (пример: он не включает флаг быстрой математики в gcc), потому что некоторые подпрограммы GSL (например, средство решения дифференциальных уравнений) не проходят свои строгие тесты на точность при наличии этих оптимизаций.

Одним из замечательных моментов в GSL является модульность библиотеки. Если вам не нужна двойная точность, вы можете скомпилировать gsl_complex.h, gsl_complex_math.h а также math.c отдельно с агрессивной оптимизацией числа с плавающей точкой (однако вам нужно удалить строку #include <config.h> в математике) Другая стратегия состоит в том, чтобы скомпилировать отдельную версию всей библиотеки с агрессивной оптимизацией чисел с плавающей запятой и проверить, не является ли точность проблемой для вашей конкретной проблемы (это мой любимый подход).

РЕДАКТИРОВАТЬ: я забыл упомянуть, что gsl_complex.h также имеет версию с плавающей точкой gsl_complex

typedef struct
{
float dat[2];
}
gsl_complex_float;
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector