Краткая предыстория. Изначально было такое
http://rsdn.org/forum/cpp/6721686.1Автор: AlexGin
Дата: 10.03.17
забавное сообщение, на которое я собирался ответить прямо там в темке, отметив что не стоит браться за тесты производительности тем, кто не может выставить правильные опции компиляторам, а пользуется только дефолтными (а они очень разные у разных компиляторов). Однако перед написанием ответа я решил всё же установить компилятор от MS, чтобы удостовериться, что за прошедшее время ничего не изменилось и он по прежнему слабенький, как я и говорил. Но в процессе этого теста вылезло ТАКОЕ, что я сразу же забыл об изначальной дискуссии и решил написать отдельное сообщение про это.
И так, я взял тесты предложенные моим собеседником в изначальной теме. Они конечно довольно сомнительные, но почему бы не проверить и на них (ведь хороший продукт должен качественно оптимизировать любой код). Только я их слегка переписал, чтобы ими можно было адекватно пользоваться (GUI в тестах???) и чтобы не было совсем стыдно за код. Но ключевая часть осталась неизменной (как я наивно думал):
| код теста |
| #define _USE_MATH_DEFINES
#include <cmath>
#include <chrono>
#include <iostream>
using namespace std;
constexpr auto N_MULTIPLY=10000000;
constexpr int N_GENERATED=1000;
int randoms[N_GENERATED];
int outputs[N_GENERATED];
double randoms_dbl[N_GENERATED];
double outputs_dbl[N_GENERATED];
template<typename F> void Measure(F f)
{
auto start=chrono::high_resolution_clock::now();
for(int i=2; i<N_MULTIPLY; i++){
for(int j=0; j<N_GENERATED; j++) f(i, j);
//if(i==0) cout<<"msvc????????????????????";
}
auto end=chrono::high_resolution_clock::now();
cout<<chrono::duration_cast<chrono::milliseconds>(end-start).count()<<" ms."<<endl;
}
int main()
{
for(int i=0; i<N_GENERATED; i++){
randoms[i]=rand();
randoms_dbl[i]=1.11*rand();
}
Measure([](int i, int j){
auto result=randoms[j]*i;
result++;
outputs[j] = result;
});
Measure([](int i, int j){
auto mult=i*1.1;
auto result=randoms_dbl[j]*mult;
result+=1.555;
outputs_dbl[j]=result;
});
Measure([](int i, int j){
auto mult=i*2*M_PI;
auto result=randoms_dbl[j]+sin(mult);
result+=0.375;
outputs_dbl[j]=result;
});
}
|
| |
Так вот запустив этот код (правда тогда в нём не было закомментированной строки) я получил такой замечательный результат:
| результат1 |
| >gcc32-sse
1425 ms.
1985 ms.
3007 ms.
>gcc32-avx
1422 ms.
1115 ms.
1675 ms.
>gcc32-avx2
734 ms.
1116 ms.
1676 ms.
>msvc32-sse
2713 ms.
3982 ms.
298870 ms.
>msvc32-avx
2741 ms.
3605 ms.
295643 ms.
>msvc32-avx2
2747 ms.
3606 ms.
295639 ms.
|
| |
Не, я конечно и делал этот тест для демонстрации преимущества gcc, но разница более чем в 100 раз показалась всё же каким-то перебором.

Тем более, что мой собеседник демонстрировал совсем других цифры. Тут была явно какая-то ошибка. Но я не мог подумать на компилятор и начал искать у себя — перебирал разные опции компилятора, варианты подключения библиотек и т.п. Но ничего не помогало. Я уже даже начал думать о магическом влияние Qt и т.п. невероятных вещах, когда мне в голову пришла совершенно наркоманская мысль: у моего собеседника в теле цикла было уведомление GUI о прогрессе прохождения теста (которое я естественно выкинул при переписывание) — поставлю ка и я нечто подобное (закомментированная строка в коде выше, причём самое забавное, что cout там никогда не выполняется). И что вы думаете? Оно заработало нормально

:
| результат2 |
| >gcc32-sse
1425 ms.
1984 ms.
3007 ms.
>gcc32-avx
1421 ms.
1116 ms.
1676 ms.
>gcc32-avx2
734 ms.
1116 ms.
1675 ms.
>msvc32-sse
1378 ms.
2039 ms.
3985 ms.
>msvc32-avx
1370 ms.
1434 ms.
3974 ms.
>msvc32-avx2
807 ms.
1399 ms.
1887 ms.
|
| |
Эти результаты меня уже ничем не удивили — всё как я и предполагал, gcc быстрее, но на небольшие проценты.
Но на фоне открывшейся чудесной "особенности" компилятора от MS данные проценты производительности уже перестают иметь какое-либо значение. На мой взгляд компилятор способный по не объяснимым причинам замедлить исполнение куска кода более чем в 100 раз вообще не может быть пригоден к использованию.
P.S. Возможно это уже общеизвестная тут информация, а это только я не знал про данную "особенность". Просто я уже давно не пользуюсь продуктом от MS и поэтому был не в курсе, а сейчас столкнулся и решил поделиться.
P.P.S. В тесте использовались компиляторы: MinGW4.9.2/MingGW6.3.0 (между ними нет разницы на данных тестах) и "Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506".
Update 13.03.17. В ходе дискуссии я написал ещё один вариант теста, уже не для измерений производительности, а для демонстрации сути проблемы (т.к. по результатам данного теста возможно не все поняли глобальность проблемы — она явно не в использование синуса) в компиляторе от MS:
http://rsdn.org/forum/cpp/6723478.1Автор: alex_public
Дата: 12.03.17
.
Так же судя по сообщениям коллег с форума можно локализовать данную проблему по версиям MSVC: подвержены версии VS 2013, 2015, 2017. И для 32-ух и для 64-ёх битного кода.