2012-03-26 5 views
4

Я использую собственную библиотеку линейных алгебр в C++ некоторое время, и я всегда старался воспользоваться преимуществами производительности векторизации. Сегодня я решил проверить, насколько векторизация действительно ускоряет мои программы. Итак, я написал следующую тестовую программу:Библиотека линейных алгебр C++ eigen3, результаты нечетной производительности

--- eigentest.cpp ---

#include <eigen3/Eigen/Dense> 
using namespace Eigen; 

#include <iostream> 

int main() { 
     Matrix4d accumulator=Matrix4d::Zero(); 
     Matrix4d randMat = Matrix4d::Random(); 
     Matrix4d constMat = Matrix4d::Constant(2); 
     for(int i=0; i<1000000; i++) { 
       randMat+=constMat; 
       accumulator+=randMat*randMat; 
     } 
     std::cout<<accumulator(0,0)<<"\n"; // To avoid optimizing everything away 
     return 0; 
} 

Затем я запустить эту программу после компиляции с различными опциями компилятора: (Результаты Арен «т один раз, много работает дают сходные результаты)

$ g++ eigentest.cpp -o eigentest -DNDEBUG -std=c++0x -march=native 
$ time ./eigentest 
5.33334e+18 

real 0m4.409s 
user 0m4.404s 
sys 0m0.000s 
$ g++ eigentest.cpp -o eigentest -DNDEBUG -std=c++0x 
$ time ./eigentest 
5.33334e+18 

real 0m4.085s 
user 0m4.040s 
sys 0m0.000s 
$ g++ eigentest.cpp -o eigentest -DNDEBUG -std=c++0x -march=native -O3 
$ time ./eigentest 
5.33334e+18 

real 0m0.147s 
user 0m0.136s 
sys 0m0.000s 
$ g++ eigentest.cpp -o eigentest -DNDEBUG -std=c++0x -O3 
$time ./eigentest 
5.33334e+18 

real 0m0.025s 
user 0m0.024s 
sys 0m0.000s 

И вот моя соответствующая информация процессора:

model name : AMD Athlon(tm) 64 X2 Dual Core Processor 5600+ 
flags  : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow extd_apicid pni cx16 lahf_lm cmp_legacy svm extapic cr8_legacy 3dn 

Я знаю, что нет векторизации, когда я не использую параметр компилятора -march=native, потому что, когда я его не использую, я никогда не получаю ошибку сегментации или неправильный результат из-за векторизации, в отличие от случая, который я использую он (с -NDEBUG).

Эти результаты заставляют меня поверить, что, по крайней мере, на моей векторизации процессора с eigen3 результаты в более медленном исполнении. Кто я должен обвинять? Мой CPU, eigen3 или gcc?

Редактировать: Чтобы устранить все сомнения, я попытался добавить параметр компилятора -DEIGEN_DONT_ALIGN в случаях, когда я пытаюсь измерить производительность случая без векторизации, и результаты те же. Кроме того, когда я добавляю -DEIGEN_DONT_ALIGN вместе с -march=native, результаты становятся очень близкими к корпусу без -march=native.

+0

, какую версию g ++ вы используете? – KillianDS

+1

На моей платформе (Intel Q9550) я получаю одинаковые скорости независимо от того, использую ли я марш = native. -O3 однако приводит к агрессивной вставке, использованию SSE и разворачиванию. Добавление -mss3 приводит к немного другой сборке с точно такой же производительностью времени выполнения. Я действительно не понимаю вашу проблему с segfault, есть ли у вас набор флагов компилятора, которые приводят к сбою вашей программы? – Bob

+0

@KillianDS my gcc version: 'gcc --version': ' gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2' – enobayram

ответ

9

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

На моей платформе я получаю около 9 мс без -march=native и около 39 мс с -march=native. Однако, если я заменить строку выше возвращения на

std::cout<<accumulator<<"\n"; 

то тайминги изменится на 78ms без -march=native и около 39ms с -march=native.

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

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

+0

Хороший улов! Компилятор действительно умнее, чем я думаю. FYI, я запустил тот же тест, я получаю 42 мс против 112 мс на моем процессоре i3 Intel (R) Core i3 M 350 @ 2.27GHz', завтра я попробую то же самое с этим CPU, упомянутым в вопросе и посмотреть, как это происходит. – enobayram