Основные способы ускорить простую программу Eigen - PullRequest
1 голос
/ 11 июня 2019

Я ищу самый быстрый способ выполнения простых операций с использованием Eigen.Есть так много доступных структур данных, трудно сказать, какая из них самая быстрая.

Я пытался заранее определить свои структуры данных, но даже тогда мой код превосходит аналогичный код на Фортране.Я догадался, что Eigen :: Vector3d - самый быстрый для моих нужд (поскольку он предопределен), но я легко могу ошибаться.Использование оптимизации -O3 во время компиляции дало мне большой импульс, но я все еще работаю в 4 раза медленнее, чем реализация того же кода на Фортране.

Я использую структуру «Атом», которая затем сохраняется в векторе «атомы», определяемом следующим образом:

struct Atom {
    std::string element;
    //double x, y, z;
    Eigen::Vector3d coordinate;
};
std::vector<Atom> atoms;

Самая медленная часть моего кода следующая:

distance = atoms[i].coordinate - atoms[j].coordinate;
distance_norm = distance.norm();

Можно ли использовать более быструю структуру данных?Или есть более быстрый способ выполнить эти основные операции?

Ответы [ 3 ]

2 голосов
/ 12 июня 2019

Как вы указали в своем комментарии, добавление флага компилятора -fno-math-errno дает вам огромное увеличение скорости.Что касается того, почему это происходит, ваш фрагмент кода показывает, что вы выполняете sqrt через distance_norm = distance.norm();.

. Это делает компилятор не установленным ERRNO после каждого sqrt (это сохраненная запись влокальная переменная потока), которая быстрее и позволяет векторизацию любого цикла, который делает это многократно. Единственный недостаток этого состоит в том, что потеря IEEE-соблюдения теряется.См. gcc man .

Еще одна вещь, которую вы можете попробовать, это добавить -march=native и добавить -mfma, если -march=native не включит его для вас (кажется, я помню,что в некоторых случаях он не был включен native и должен был быть включен вручную - проверьте детали ).И как всегда с Eigen, вы можете отключить проверку границ с помощью -DNDEBUG.

SoA вместо AoS !!!Если производительность действительно является реальной проблемой, рассмотрите возможность использования одной матрицы 4xN для хранения позиций (и пусть Atom сохранит индекс столбца вместо Eigen::Vector3d).В небольшом фрагменте кода, который вы показали, это не должно иметь большого значения, но, в зависимости от остального кода, может привести к еще одному огромному увеличению производительности.

0 голосов
/ 11 июня 2019

Либо попробуйте другой компилятор, такой как компилятор Intel C ++ (бесплатно для академического и некоммерческого использования), либо используйте другие библиотеки, такие как Intel MKL (намного быстрее, чем ваш собственный код), или даже другие реализации BLAS / LAPACK для плотных матриц, PARDISO или SuperLU. (не уверен, что все еще существует) для разреженных матриц.

0 голосов
/ 11 июня 2019

Учитывая, что у вас ~ 4х, возможно, стоит проверить, что вы включили векторизацию, такую ​​как AVX или AVX2, во время компиляции. Конечно, есть также SSE2 (~ 2x) и AVX512 (~ 8x) при работе с парными разрядами.

...