Re[6]: Очередной "шедевр" от MS
От: Zhendos  
Дата: 12.03.17 13:34
Оценка:
Здравствуйте, AlexGin, Вы писали:

AG>Здравствуйте, alex_public, Вы писали:


_>>А ты случаем не путаешь медленные вычисления и замораживание интерфейса при таких вычислениях (естественно в том случае, если это писал криворукий программист)? ))) Потому как от второй проблемы расстановка дополнительных циклов обработки сообщений ещё может помочь, а вот с первой проблемой ничем подобным помочь нельзя. А то бы иначе сейчас все суперкомпьютеры выстроились в очередь за "прокачкой сообщений от ОС"...

AG>Hint: multithreading — это единственное решение данной проблемы в Production.

_>>Самое забавное, что ты даже не понял что ты собственно сделал в своём и почему он снова заработал. ) И тебя даже не смущает тот факт, что если заменить цикл обработки сообщений на какой-нибудь cout<<"xaxa"; то всё равно проблема решается.


AG>Sorry, но это ты не понял:

AG>Любой "оконный" вывод в современных графических операционных системах связан с обменом сообщениями операционной системы.
AG>Без них не отработает ничего(ни вывод std::cout на консоль, ни обновление прогресс бара).
AG>В данном случае, этот вывод (за счёт прокачки сообщений реализованной в недрах OS Windows) просто обеспечивал "сторонний эффект".
AG>Только вот тут редкий случай, когда данный "сторонний эффект" действует положительно, а не отрицательно
AG>Когда я явно сделал ту же прокачку — всё вернулось на свои места.

Весьма странная точка зрения.

Определимся с помощью чего мы делаем замеры, с помощью абсолютного времени или каким-то
образом замеряем время которое дала ОС данному потоку.

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

В первом случае (случае учета абсолютного времени) системные вызовы теоритически могут влиять,
т.к. ОС в целях улучшения видимой пользователем latency может чуть уменшать или увеличивать
квант времени приложению, и по какой-то причине может решить что приложение с вызовом ProcessMessages
это приложение с которым работает пользователь, а без этого вызова — background process, у которого
можно динамический приоритет планировщика потоков понизить.

Но разве не стоит просто забить на "первый вариант" и не учитывать при benchmarks?
Re[2]: Очередной "шедевр" от MS
От: N. I.  
Дата: 12.03.17 14:59
Оценка:
AlexGin:

AG>3) Игра опциями настройки компилятора, как бы ими не играть, не позволят серьезно изменить соотношение — т.е.

AG>для Windows систем — (хотим мы это признавать или нет) MS компилятор окажется быстрее конкурента.

При использовании -flto в MinGW у меня везде показывается нулевое время (видимо, из-за того, что из заполняемых массивов никто ничего не читает)
Отредактировано 19.08.2017 12:31 N. I. . Предыдущая версия .
Re[6]: Очередной "шедевр" от MS
От: alex_public  
Дата: 12.03.17 15:27
Оценка:
Здравствуйте, Serg27, Вы писали:

E>>>Истинный виновник тут, конечно, тот, кто столь сложным заполняет массив константой, известной на момент компиляции...

AG>>Массив заполняется случайными значениями, перемноженными на индекс прохода по циклу
S>Егор абсолютно прав. Посмотрите код внимательно. Там где "Массив заполняется случайными значениями, перемноженными на индекс прохода по циклу" проблем нет (это в коде ТС).

Вообще то есть.

S>В моем коде оставлено только два варианта с одинаковым результатом вычислений, причем результат мог быть вычислен во время компиляции. цитата:

S>

S>Т.е. оптимизация для fun1 дала выигрыш в 27 раз, а для fun2 в 1,5. Глядя на код, оптимизация конечно должна была быть в N_MULTIPLY раз, так результат работы кода — заполненный массив outputs_dbl значением sin(N_MULTIPLY). Но по каким-то соображениям компилятор этого не сделал.

S>Напомню, что N_MULTIPLY = 1000000. Т.е gcc тоже облажался с оптимизацией... Причем очень сильно...

А причём тут вообще gcc? Ты запускал свой код на нём? Если же ты говоришь про изначальный тест, то там нигде нет заполнения массива известными на момент компиляции значениями.
Re[2]: Bug report to MS
От: alex_public  
Дата: 12.03.17 15:40
Оценка: 6 (1) +2
Здравствуйте, Serg27, Вы писали:

S>Я не поленился и сделал bug report — connect.microsoft.com

S>Предмет бага — разный уровень оптимизации для очень близкого кода. Посланный код основан на rsdn
Автор: Serg27
Дата: 11.03.17


S>P.S.

S>Хотел бы еще раз отметить, что для этого вырожденного кода включение оптимизации в одном случае дает выигрыш в 27 раз, а в другом в 1.5. При идеальной же оптимизации выигрыш должен был быть в N_MULTIPLY = 1000000 раз. С этим не справился ни один компилятор...
S>P.P.S.
S>Самого кода пока не видно. Они декларируют задержку в появлении загруженных файлов от нескольких часов до суток.

Твой код некорректен в роли проверки быстродействия — никто тебе не гарантирует инлайн лямбд в таких ситуациях. Я то это использовал для краткости записи (проверив что это никак не влияет на цифры в моём конкретном случае). Но в твоём случае это абсолютно не известно. Далее, у тебя там используется ряд мест потенциально попадающих под разные оптимизации. В общем я бы на месте MS даже не стал бы рассматривать подобную бредятину, т.к. в ней не видно никаких очевидных ошибок. Если уж ты хотел сделать краткий код демонстрирующий суть проблемы, то это должно было бы выглядеть так:

#include <chrono>
#include <iostream>

using namespace std;

template<typename F> void Measure(F f)
{
    auto begin=chrono::high_resolution_clock::now();
    f();
    auto end=chrono::high_resolution_clock::now();
    cout<<chrono::duration_cast<chrono::milliseconds>(end-begin).count()<<" ms."<<endl;
}

constexpr auto N_MULTIPLY=10000000;
constexpr int N_GENERATED=1000;

float inputs[N_GENERATED];
float outputs[N_GENERATED];

void f1()
{
    for(int i=2; i<N_MULTIPLY; i++)
        for(int j=0; j<N_GENERATED; j++)
            outputs[j]=inputs[j]*i;
}

void f2()
{
    for(int i=2; i<N_MULTIPLY; i++){
        for(int j=0; j<N_GENERATED; j++)
            outputs[j]=inputs[j]*i;
        if(i==0) cout<<"msvc????????????????????";
    }
}

int main()
{
    Measure(f1);
    Measure(f2);
}


И результаты данного теста:
>gcc32-sse
815 ms.
815 ms.

>gcc32-avx
402 ms.
402 ms.

>gcc32-avx2
402 ms.
402 ms.

>msvc32-sse
2387 ms.
738 ms.

>msvc32-avx
2639 ms.
663 ms.

>msvc32-avx2
2640 ms.
660 ms.


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

P.S. Да, при желание можешь заменить outputs[j]=inputs[j]*i; на скажем outputs[j]=inputs[j]*sin(0.1f*i); чтобы получить заявленную дикую разницу в 100 раз. Но это всё равно та же самая проблема, просто на sin она видна особо ярко. )))
Отредактировано 12.03.2017 16:31 alex_public . Предыдущая версия .
Re[2]: Очередной "шедевр" от CLang :-)
От: alex_public  
Дата: 12.03.17 15:48
Оценка: +1
Здравствуйте, Serg27, Вы писали:

S>После того как я послал bug report в MS, я решил проверить, а как справляется с этим вырожденным примером CLang (по мнению многих лучший компилятор нашего времени). Так как toolset Clang установлен у меня в VS2015, то это делается переключением toolset в настройках проекта.

S>
  Code
S>
S>#include <cmath>
S>#include <time.h>
S>#include <iostream>

S>using namespace std;

S>constexpr auto N_MULTIPLY = 1000000;// 10000000;
S>constexpr int N_GENERATED = 1000;
S>namespace
S>{
S>    double outputs_dbl[N_GENERATED];
S>}
S>template<typename F> void Measure(F f)
S>{
S>    for (int i = 2; i<N_MULTIPLY; i++) {
S>        for (int j = 0; j<N_GENERATED; j++)  f(i, j);
S>    }
S>}
S>template<typename F> void Measure2(F f)
S>{
S>    int i = 1;
S>    for (i = 2; i<N_MULTIPLY; i++) {
S>        for (int j = 0; j<N_GENERATED; j++)  f(i, j);
S>    }
S>    if (i == 0) cout << "msvc";
S>}

S>void fun1(int i, int j)
S>{
S>    outputs_dbl[j%N_GENERATED] = sin((double)i);
S>}
S>inline void fun2(int i, int j)
S>{
S>    outputs_dbl[j] = sin((double)i);
S>}
S>int main()
S>{
S>    auto start = clock();
S>    Measure(fun1);
S>    auto finish = clock();
S>    double duration = (double)(finish - start) / CLOCKS_PER_SEC;
S>    cout << "Measure(fun1) - " << duration << " s." << endl;
S>//    cout << outputs_dbl[0] << " " << outputs_dbl[N_GENERATED - 1] << " " << sin((double)(N_MULTIPLY - 1)) << endl;

S>    start = clock();
S>    Measure(fun2);
S>    finish = clock();
S>    duration = (double)(finish - start) / CLOCKS_PER_SEC;
S>    cout << "Measure(fun2) - " << duration << " s." << endl;

S>    start = clock();
S>    Measure2(fun1);
S>    finish = clock();
S>    duration = (double)(finish - start) / CLOCKS_PER_SEC;
S>    cout << "Measure2(fun1) - " << duration << " s." << endl;

S>    start = clock();
S>    Measure2(fun2);
S>    finish = clock();
S>    duration = (double)(finish - start) / CLOCKS_PER_SEC;
S>    cout << "Measure2(fun2) - " << duration << " s." << endl;

S>}
S>


S>MS VC++ результат:
S>

S>Measure(fun1) — 1.481 s.
S>Measure(fun2) — 26.168 s.
S>Measure2(fun1) — 1.392 s.
S>Measure2(fun2) — 0.207 s.

S>CLang результат:
S>

S>Measure(fun1) — 30.267 s.
S>Measure(fun2) — 27.868 s.
S>Measure2(fun1) — 29.742 s.
S>Measure2(fun2) — 27.921 s.

S>командная строка компилятора:
S>

S>-fpic "stdafx.h" -fstack-protector "x64\Release\" -fno-strict-aliasing -ffunction-sections -gline-tables-only -O3 -x c++-header -D "NDEBUG" -D "_CONSOLE" -D "_UNICODE" -D "UNICODE" -fno-rtti -fomit-frame-pointer -fdata-sections -fno-ms-compatibility -fexceptions -o "x64\Release\testRSDN.obj" -fms-extensions -fno-short-enums

S>
S>Вывод в стиле ТС :))
S>!!!Как видно Clang уступает MSVC и вообще не пригоден к использованию!!!!
S>

Вообще то как раз твой тест показывает, что Clang нет никаких подобных ошибок — он для обоих вариантов кода выдаёт одинаковый результат. Почему такие абсолютные цифры — это отдельный вопрос (например там не произошёл инлайн лямбд, который тебе никто не гарантировал), с которым ты можешь поразбираться при желание. Но данной ошибки в Clang нет. В отличие от продукта MS. )))
Re[6]: Очередной "шедевр" от MS
От: alex_public  
Дата: 12.03.17 15:59
Оценка: +2
Здравствуйте, AlexGin, Вы писали:

_>>А ты случаем не путаешь медленные вычисления и замораживание интерфейса при таких вычислениях (естественно в том случае, если это писал криворукий программист)? ))) Потому как от второй проблемы расстановка дополнительных циклов обработки сообщений ещё может помочь, а вот с первой проблемой ничем подобным помочь нельзя. А то бы иначе сейчас все суперкомпьютеры выстроились в очередь за "прокачкой сообщений от ОС"...

AG>Hint: multithreading — это единственное решение данной проблемы в Production.

Ну давай, перепиши свой пример, чтобы у тебя вычисления шли в отдельном потоке и посмотрим на твой шок от результата.

_>>Самое забавное, что ты даже не понял что ты собственно сделал в своём и почему он снова заработал. ) И тебя даже не смущает тот факт, что если заменить цикл обработки сообщений на какой-нибудь cout<<"xaxa"; то всё равно проблема решается.

AG>Sorry, но это ты не понял:
AG>Любой "оконный" вывод в современных графических операционных системах связан с обменом сообщениями операционной системы.
AG>Без них не отработает ничего(ни вывод std::cout на консоль, ни обновление прогресс бара).
AG>В данном случае, этот вывод (за счёт прокачки сообщений реализованной в недрах OS Windows) просто обеспечивал "сторонний эффект".
AG>Только вот тут редкий случай, когда данный "сторонний эффект" действует положительно, а не отрицательно
AG>Когда я явно сделал ту же прокачку — всё вернулось на свои места.

Я даже оставлю без комментариев очаровательную теорию о том, что cout работает через очередь сообщений винды и попробую всё же воззвать к элементарной логике. А тебя совсем не смущает, что в моём коде (но если ты заменишь в своём коде свой "цикл сообщений" на данную строчку, то всё аналогично нормально заработает) используется строчка if(i==0) cout<<"msvc????????????????????"; т.е. данный cout не выполняется никогда! Но при этом он почему-то ускоряет исполнение кода в 100 раз...

_>>С таким подходом нельзя даже приближаться к тестам на производительность. И да, дефолтные опции Qt весьма далеки от максимальной эффективности.

AG>
AG>Пойми правильно, уважаемый alex_public, что я ведь не собираюсь "с пеной у рта" доказывать, что MSVC — the best
AG>Просто хочу докопаться до истины.
AG>Окажется, что в этом эксперименте оба компилятора примерно одинаковы, или даже MinGW чуть быстрее — милости просим!

Ну вот реальные результаты (без учёта багов msvc) для данного кода на максимальных настройках оптимизации ты можешь посмотреть в моём первом сообщение в данной теме под названием "результат2". В зависимости от целевой архитектуры процессора и конкретного теста результаты разные, но в среднем я бы сказал что gcc чуть лучше. Хотя для подавляющего большинства ПО можно считать что разницы нет вообще (опять же если без учёта багов msvc).
Re[7]: Очередной "шедевр" от MS
От: AlexGin Беларусь  
Дата: 12.03.17 22:23
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Я даже оставлю без комментариев очаровательную теорию о том, что cout работает через очередь сообщений винды и попробую всё же воззвать к элементарной логике. А тебя совсем не смущает, что в моём коде (но если ты заменишь в своём коде свой "цикл сообщений" на данную строчку, то всё аналогично нормально заработает) используется строчка if(i==0) cout<<"msvc????????????????????"; т.е. данный cout не выполняется никогда! Но при этом он почему-то ускоряет исполнение кода в 100 раз...


Да, есть проблема — bug компилятора MSVC. Этот баг связан с кодогенерацией при оптимизации.

AG>>

AG>>Пойми правильно, уважаемый alex_public, что я ведь не собираюсь "с пеной у рта" доказывать, что MSVC — the best
AG>>Просто хочу докопаться до истины.
AG>>Окажется, что в этом эксперименте оба компилятора примерно одинаковы, или даже MinGW чуть быстрее — милости просим!

_>Ну вот реальные результаты (без учёта багов msvc) для данного кода на максимальных настройках оптимизации ты можешь посмотреть в моём первом сообщение в данной теме под названием "результат2". В зависимости от целевой архитектуры процессора и конкретного теста результаты разные, но в среднем я бы сказал что gcc чуть лучше. Хотя для подавляющего большинства ПО можно считать что разницы нет вообще (опять же если без учёта багов msvc).

Вполне возможно, что результаты тестов примерно одинаковые. Возможно даже, что MinGW чуть эффективнее.
Почему же тогда первоначальный тест (на Qt) давал такие разные результаты, с явным преимуществом MSVC. Будем посмотреть
Re[8]: Очередной "шедевр" от MS
От: alex_public  
Дата: 12.03.17 23:36
Оценка:
Здравствуйте, AlexGin, Вы писали:

_>>Ну вот реальные результаты (без учёта багов msvc) для данного кода на максимальных настройках оптимизации ты можешь посмотреть в моём первом сообщение в данной теме под названием "результат2". В зависимости от целевой архитектуры процессора и конкретного теста результаты разные, но в среднем я бы сказал что gcc чуть лучше. Хотя для подавляющего большинства ПО можно считать что разницы нет вообще (опять же если без учёта багов msvc).

AG>Вполне возможно, что результаты тестов примерно одинаковые. Возможно даже, что MinGW чуть эффективнее.
AG>Почему же тогда первоначальный тест (на Qt) давал такие разные результаты, с явным преимуществом MSVC. Будем посмотреть

Потому что ты использовал дефолтные (с которыми собрана сама библиотека, но это не значит что надо их использовать для своего приложения) настройки Qt для компилятора, а не свои. Для msvc у них там почти максимальные настройки — разве что только avx не используется. А для gcc там используется во-первых не полная оптимизация (-O2, а не -O3), а во-вторых скорее всего не используется даже просто sse (у компилятора msvc это режим по умолчанию, а у gcc такие вещи надо указывать руками и я не помню указано ли подобное при дефолтной сборке Qt).

Кстати, я вот предпочитаю и саму Qt использовать своей сборки, со своими опциями. Но это так, уже тема отдельного разговора. )))
Re[2]: Очередной "шедевр" от CLang :-)
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 13.03.17 19:31
Оценка: +4 -2 :))
Здравствуйте, Serg27, Вы писали:
S>Вывод в стиле ТС :))
S>!!!Как видно Clang уступает MSVC и вообще не пригоден к использованию!!!!

Его "стиль" напоминает мне ребёнка, который нашёл лужу и теперь прыгает в ней, пытаясь обрызгать как можно больше окружающих
[КУ] оккупировала армия.
Re[3]: Bug report to MS
От: fddima  
Дата: 13.03.17 21:15
Оценка:
Здравствуйте, fddima, Вы писали:

F> Мне говорили — там аттачи больше года не работают. Не появятся через день — смело вставляй ссылку.

А вот вам и высокоуровневая оптимизация: аттач приаттачил, написали в окошке, что мол будьте терпеливы — они появятся потом, потому что кеширование и валидация бла бла бла! И в /dev/null их, в /dev/null.
Re[3]: Очередной "шедевр" от CLang :-)
От: alex_public  
Дата: 14.03.17 13:48
Оценка: +6
Здравствуйте, koandrew, Вы писали:

K>Его "стиль" напоминает мне ребёнка, который нашёл лужу и теперь прыгает в ней, пытаясь обрызгать как можно больше окружающих


О, я смотрю тебе очень хочется написать что-нибудь и в профильном разделе форума, а не только в "политике" или "о жизни". Но при этом никакой технической информации по данной серьёзной профильной теме ты из себя выжать не смог, так что решил по привычке сразу перейти к обсуждению участников дискуссии. Только боюсь тебя огорчить, но в данных разделах форума подобное никому не интересно. )
Re[4]: Очередной "шедевр" от CLang :-)
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 14.03.17 13:58
Оценка: +1 -5
Здравствуйте, alex_public, Вы писали:

_>О, я смотрю тебе очень хочется написать что-нибудь и в профильном разделе форума, а не только в "политике" или "о жизни". Но при этом никакой технической информации по данной серьёзной профильной теме ты из себя выжать не смог, так что решил по привычке сразу перейти к обсуждению участников дискуссии. Только боюсь тебя огорчить, но в данных разделах форума подобное никому не интересно. )


У тебя мания величия, если ты думаешь, что твоё мнение о том, кто и где что может писать кому-то интересно.
[КУ] оккупировала армия.
Re[2]: Очередной "шедевр" от MS
От: vdimas Россия  
Дата: 19.03.17 00:17
Оценка:
Здравствуйте, Serg27, Вы писали:

Еще более минимально вот так:
void fun1(unsigned i, unsigned j) {
    outputs_dbl[j+0-0] = sin((double)i);
}


Причем, outputs_dbl[j+0] или outputs_dbl[j-0] эффекта не дает, надо именно j+0-0.
От опций /O2 или /Ox поведение не зависит, зависит только от отсутствия /Os.

В случае j+0 синус вызывается на каждом шаге, а в случае j+0-0 — только по внешнему циклу.

S>Глядя на код, оптимизация конечно должна была быть в N_MULTIPLY раз


Чего это?
sin(x) считается на регистрах, а результат надо 1000 раз положить в массив длиной 8 млн байт.
Тут уже скорость записи в ОП сказывается.


S>так результат работы кода — заполненный массив outputs_dbl значением sin(N_MULTIPLY). Но по каким-то соображениям компилятор этого не сделал.


Наверно потому, что sin не является intrinsics.
Это честная библиотечная ф-ия, которая честно линкуется.
Re[2]: Bug report to MS
От: Serg27  
Дата: 19.08.17 09:43
Оценка: 6 (2)
Здравствуйте, Serg27, Вы писали:

S>Я не поленился и сделал bug report — connect.microsoft.com

S>Предмет бага — разный уровень оптимизации для очень близкого кода. Посланный код основан на rsdn
Автор: Serg27
Дата: 11.03.17


ну вот прошло 5 месяцев и пришел ответ:

Thanks for the great bug report. I looked into the issue, and it turns out that the sin function call in fun1 is being hoisted out of the innermost loop, while that's not happening in the case of fun2. This explains the performance difference.

We will keep looking further into the reasoning and send out an update.

Thanks,
Amit

Возможно поправят оптимизацию, раз баг дошел до разработчика...
Спасибо тем, кто "лайкнул" этот баг у них на сайте — иначе бы вообще руки не дошли.
Отредактировано 19.08.2017 9:45 Serg27 . Предыдущая версия .
Re: Генерация макрoобёрток, возможно ли?
От: Nick-77  
Дата: 14.09.17 16:10
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Эти результаты меня уже ничем не удивили — всё как я и предполагал, gcc быстрее, но на небольшие проценты.


_>Но на фоне открывшейся чудесной "особенности" компилятора от MS данные проценты производительности уже перестают иметь какое-либо значение. На мой взгляд компилятор способный по не объяснимым причинам замедлить исполнение куска кода более чем в 100 раз вообще не может быть пригоден к использованию.



Добрый вечер, а clang тестить не пробовали?
Re[3]: Bug report to MS
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 09.01.18 12:45
Оценка:
Здравствуйте, Serg27, Вы писали:

S>Возможно поправят оптимизацию, раз баг дошел до разработчика...

S>Спасибо тем, кто "лайкнул" этот баг у них на сайте — иначе бы вообще руки не дошли.

Страница с багом не открывается. проверено на новой версии компилятора 15.5 с кучей оптимизаций — не исправлено. Увы! Как-то стрёмно жить с таким компилятором.
Re[4]: Re[3]: Bug report to MS
От: Yaroslav  
Дата: 20.01.18 13:18
Оценка:
Читаю я этот пример и думаю.
А что вы тут собственно меряете? Как компилятор константы оптимизирует???

volatile на индексы ставить не пробовали?
Re[5]: Bug report to MS
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 20.01.18 15:10
Оценка:
Здравствуйте, Yaroslav, Вы писали:

Y>Читаю я этот пример и думаю.

Y>А что вы тут собственно меряете? Как компилятор константы оптимизирует???

Нет.

Y>volatile на индексы ставить не пробовали?


Нет.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.