Как стать автором
Обновить

Комментарии 24

Да уж, век учись, а С++ все равно не выучишь :)
За статью спасибо, прибавилось ясности в работе компилятора!
С++ — язык, который изучается постепенно :)
Статья ниразу не про язык. Статья про конкретный компилятор и его ключики.
Там же про CLR, не про native C++.
Я так понимаю, что это фича Visual Studio, а не CLR, с Native то же самое, если мой английский меня не подводит.
Похоже на то. Просто ваша первая ссылка про CLR совсем, вот я и придрался :)
Не думаю что это можно рассматривать как фичу вижуал студио, т.к. между native и CLR огромная пропасть, так что не обязательно всё поддерживаемое в native есть в CLR, и в некоторых случаях, естественно, наоборот.
Да, я неправ с первой ссылкой. Но Edit and Continue действительно не работает и там, и там, во второй ссылке прямо написано, что у MS есть две заявки на исправление этого — и для Native, и для CLR.
Статья интересная, в плане экспериментов :-) надо только пару вещей для начинающих отметить:

1. бенчмарки на debug build делать бессмысленно, он не для скорости предназначен, а для максимума проверок

2. отключать проверки в debug build крайне нежелательно
1. Если вы НЕ используете Debug, то бессмысленно. А если с вашим приложением вам же невозможно работать, то имеет смысл бенчмаркить и ускорять Debug — вам же от этого лучше.
Всё-равно не понимаю, зачем в дебаге бенчить? Всё-равно результаты бенча в дебаге неадекватны.
Так дело не в бенче самом (хотя для самого дебага бенчмарк вполне адекватен), а в том, чтобы понять что конкретно тормозит и исправить это.
Бывают случаи, когда из-за таких замедлений дебажный билд вообще теряет целесообразность — на нем невозможно дождаться результата проверок, так что большое спасибо автору за статью, особенно насчет прагм, очень ценная информация.
Единственное название не совсем соответствует, что видимо вас и смутило, статья все же об управлении скоростью дебажного билда.
А иногда не только невозможно дождаться, а просто ничего не работает, например если realtime данные параллельно должны обрабатываться, а они не успевают.
Но в таких случаях ихо проще включить отладочную инфу для релиза, ну и при необходимости оптимизации убрать, вместо того чтобы отключать все дебаг проверки и заморочки. Получится такой дебаг-релиз :)
например если realtime данные параллельно должны обрабатываться, а они не успевают

Хм, а что значит должны — как вы гарантируете, что данные точно обработаются без синхронизации?
Я не очень понял вопрос. Суть в том что идёт поток данных который нужно на лету обрабатывать, и если дебаг-версия за ним не успевает, то ничего не выйдет (по крайней мере эту часть кода придётся вынести в релиз или отключать всяческие дебаг проверки).
В смысле происходит переполнение буфера, который отведен для этого потока?
Не успевают обрабатываться данные. Можно, конечно, это назвать «переполнение буфера», но не в смысле уязвимости :) Будет потеря или накопление данных.
Удивительно, что проверки под _DEBUG тормозят it++ по сравнению с ++it более чем в 2 раза (3 vs 8). Там добавка-то: объект на стеке создать, копи-конструктор два раза позвать, и деструктор.
В этом свете ещё более удивительно, что положить 256 байт на стек на каждый вызов функции тормозит всего на 20%. В стек положить, конечно, быстро, но по идее данные из-за этого станут нелокальными => промахи кэша. Хотя с другой стороны, в дебаге и так уже всё нелокально шокапец, так что…
А вот за инфу про /ZI отдельное спасибо, будем знать :)
L1 кеш куда больше 256 байт, а стек попадает примерно в одно и то же место при последовательных вызовах. Это около 100 тактов. Кроме того не все вызовы пишут 240 байт, например operator ++ пишет всего 28 байт, для чего делается 7 mov.

Основные тормозища видимо из-за… критической секции в деструкторе отладочного итераторе!
Понятно, что единоразово 256 байт положить в кэш это не страшно, но «если все так будут делать», то раз-два и нету больше кэша :)

Странно, не замечал чтобы критическая секция сама по себе тормозила, она же на атомиках и только в случае неудачи сваливается на мьютекс. По моим замерам, критическая секция при низкой конкуренции не стоит практически ничего (на уровне вызова функции).
Вложенные вызовы убьют кеш конечно. Но тут они последовательные. И записываются одни и те же 256 байт (или меньше). Фактически фрейм растет и заполняется маркерами, но остается маленьким, горячим и полностью в L1.

Под критической секцией я имел в виду еще и всю прикрытую ей работу, а именно _Orphan_me. Там длинная цепочка унаследованных деструкторов, под десяток call-ов, ну и в самом низу защищенное локом обновление списка итераторов контейнера. Те. недешевый сам по себе деструктор вызывается в 3 раза чаще, отчего и основные тормоза.
Не, ну если там списки итераторов нагорожены и десятки унаследованных деструкторов, то понятно… Не думал, что всё настолько жёстко :)
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории