Здравствуйте, 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?
AlexGin:
AG>3) Игра опциями настройки компилятора, как бы ими не играть, не позволят серьезно изменить соотношение — т.е. AG>для Windows систем — (хотим мы это признавать или нет) MS компилятор окажется быстрее конкурента.
При использовании -flto в MinGW у меня везде показывается нулевое время (видимо, из-за того, что из заполняемых массивов никто ничего не читает)
Здравствуйте, 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? Ты запускал свой код на нём? Если же ты говоришь про изначальный тест, то там нигде нет заполнения массива известными на момент компиляции значениями.
Здравствуйте, Serg27, Вы писали:
S>Я не поленился и сделал bug report — connect.microsoft.com S>Предмет бага — разный уровень оптимизации для очень близкого кода. Посланный код основан на rsdn
S>P.S. S>Хотел бы еще раз отметить, что для этого вырожденного кода включение оптимизации в одном случае дает выигрыш в 27 раз, а в другом в 1.5. При идеальной же оптимизации выигрыш должен был быть в N_MULTIPLY = 1000000 раз. С этим не справился ни один компилятор... S>P.P.S. S>Самого кода пока не видно. Они декларируют задержку в появлении загруженных файлов от нескольких часов до суток.
Твой код некорректен в роли проверки быстродействия — никто тебе не гарантирует инлайн лямбд в таких ситуациях. Я то это использовал для краткости записи (проверив что это никак не влияет на цифры в моём конкретном случае). Но в твоём случае это абсолютно не известно. Далее, у тебя там используется ряд мест потенциально попадающих под разные оптимизации. В общем я бы на месте MS даже не стал бы рассматривать подобную бредятину, т.к. в ней не видно никаких очевидных ошибок. Если уж ты хотел сделать краткий код демонстрирующий суть проблемы, то это должно было бы выглядеть так:
Тут ключевой нюанс не в самих абсолютных цифрах или сравнение компиляторов, а в том, что данная программа собранная компилятором без откровенных багов должна выдавать одинаковые цифры при любых настройках оптимизации.
P.S. Да, при желание можешь заменить outputs[j]=inputs[j]*i; на скажем outputs[j]=inputs[j]*sin(0.1f*i); чтобы получить заявленную дикую разницу в 100 раз. Но это всё равно та же самая проблема, просто на sin она видна особо ярко. )))
Здравствуйте, Serg27, Вы писали: S>После того как я послал bug report в MS, я решил проверить, а как справляется с этим вырожденным примером CLang (по мнению многих лучший компилятор нашего времени). Так как toolset Clang установлен у меня в VS2015, то это делается переключением toolset в настройках проекта. S>
S> S>Вывод в стиле ТС :)) S>!!!Как видно Clang уступает MSVC и вообще не пригоден к использованию!!!! S>
Вообще то как раз твой тест показывает, что Clang нет никаких подобных ошибок — он для обоих вариантов кода выдаёт одинаковый результат. Почему такие абсолютные цифры — это отдельный вопрос (например там не произошёл инлайн лямбд, который тебе никто не гарантировал), с которым ты можешь поразбираться при желание. Но данной ошибки в Clang нет. В отличие от продукта MS. )))
Здравствуйте, 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).
Здравствуйте, 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. Будем посмотреть
Здравствуйте, AlexGin, Вы писали:
_>>Ну вот реальные результаты (без учёта багов msvc) для данного кода на максимальных настройках оптимизации ты можешь посмотреть в моём первом сообщение в данной теме под названием "результат2". В зависимости от целевой архитектуры процессора и конкретного теста результаты разные, но в среднем я бы сказал что gcc чуть лучше. Хотя для подавляющего большинства ПО можно считать что разницы нет вообще (опять же если без учёта багов msvc). AG>Вполне возможно, что результаты тестов примерно одинаковые. Возможно даже, что MinGW чуть эффективнее. AG>Почему же тогда первоначальный тест (на Qt) давал такие разные результаты, с явным преимуществом MSVC. Будем посмотреть
Потому что ты использовал дефолтные (с которыми собрана сама библиотека, но это не значит что надо их использовать для своего приложения) настройки Qt для компилятора, а не свои. Для msvc у них там почти максимальные настройки — разве что только avx не используется. А для gcc там используется во-первых не полная оптимизация (-O2, а не -O3), а во-вторых скорее всего не используется даже просто sse (у компилятора msvc это режим по умолчанию, а у gcc такие вещи надо указывать руками и я не помню указано ли подобное при дефолтной сборке Qt).
Кстати, я вот предпочитаю и саму Qt использовать своей сборки, со своими опциями. Но это так, уже тема отдельного разговора. )))
Здравствуйте, fddima, Вы писали:
F> Мне говорили — там аттачи больше года не работают. Не появятся через день — смело вставляй ссылку.
А вот вам и высокоуровневая оптимизация: аттач приаттачил, написали в окошке, что мол будьте терпеливы — они появятся потом, потому что кеширование и валидация бла бла бла! И в /dev/null их, в /dev/null.
Здравствуйте, koandrew, Вы писали:
K>Его "стиль" напоминает мне ребёнка, который нашёл лужу и теперь прыгает в ней, пытаясь обрызгать как можно больше окружающих
О, я смотрю тебе очень хочется написать что-нибудь и в профильном разделе форума, а не только в "политике" или "о жизни". Но при этом никакой технической информации по данной серьёзной профильной теме ты из себя выжать не смог, так что решил по привычке сразу перейти к обсуждению участников дискуссии. Только боюсь тебя огорчить, но в данных разделах форума подобное никому не интересно. )
Здравствуйте, alex_public, Вы писали:
_>О, я смотрю тебе очень хочется написать что-нибудь и в профильном разделе форума, а не только в "политике" или "о жизни". Но при этом никакой технической информации по данной серьёзной профильной теме ты из себя выжать не смог, так что решил по привычке сразу перейти к обсуждению участников дискуссии. Только боюсь тебя огорчить, но в данных разделах форума подобное никому не интересно. )
У тебя мания величия, если ты думаешь, что твоё мнение о том, кто и где что может писать кому-то интересно.
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.
Это честная библиотечная ф-ия, которая честно линкуется.
Здравствуйте, Serg27, Вы писали:
S>Я не поленился и сделал bug report — connect.microsoft.com S>Предмет бага — разный уровень оптимизации для очень близкого кода. Посланный код основан на rsdn
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
Возможно поправят оптимизацию, раз баг дошел до разработчика...
Спасибо тем, кто "лайкнул" этот баг у них на сайте — иначе бы вообще руки не дошли.
Здравствуйте, alex_public, Вы писали:
_>Эти результаты меня уже ничем не удивили — всё как я и предполагал, gcc быстрее, но на небольшие проценты.
_>Но на фоне открывшейся чудесной "особенности" компилятора от MS данные проценты производительности уже перестают иметь какое-либо значение. На мой взгляд компилятор способный по не объяснимым причинам замедлить исполнение куска кода более чем в 100 раз вообще не может быть пригоден к использованию.
Здравствуйте, Serg27, Вы писали:
S>Возможно поправят оптимизацию, раз баг дошел до разработчика... S>Спасибо тем, кто "лайкнул" этот баг у них на сайте — иначе бы вообще руки не дошли.