Есть у нас в проекте ручной разворачиватель классов через лямбды, используется он в туевой куче месте в важных с точки зрения производительности местах. Это хозяйство (проект) собирается под разные платформы, соответственно смотреть километровые простыни -Winline под гсс нет никакого желания. Сейчас есть режим работы приложения, когда оно прогоняет на тестовых данных все сомнительные функции и если "оптимизированная версия" медленнее неоптимизированной, то верещит. Прогонять тоже занимает какое то время, поэтому хочется придумать волбешную пилюлю, чтобы съел ее и сразу в момент вызова функции (внешне разворачивалка выглядит как цепочка рекурсивных функций) мог узнать заинлайнилась она или нет? Есть идеи?
<Подпись удалена модератором>
Re: Как узнать в рантайме была ли заинлайнена функция?
Здравствуйте, denisko, Вы писали:
D>Есть у нас в проекте ручной разворачиватель классов через лямбды, используется он в туевой куче месте в важных с точки зрения производительности местах. Это хозяйство (проект) собирается под разные платформы, соответственно смотреть километровые простыни -Winline под гсс нет никакого желания. Сейчас есть режим работы приложения, когда оно прогоняет на тестовых данных все сомнительные функции и если "оптимизированная версия" медленнее неоптимизированной, то верещит. Прогонять тоже занимает какое то время, поэтому хочется придумать волбешную пилюлю, чтобы съел ее и сразу в момент вызова функции (внешне разворачивалка выглядит как цепочка рекурсивных функций) мог узнать заинлайнилась она или нет? Есть идеи?
В принципе, инлайн от неинлайна, (не глядя в ассемблер) отличается наличием собственного фрейма.
Теоретически можно попробовать что-то вроде:
bool is_inline_f(char a, const char *a_addr)
{
return &a == a_addr; // т.е. если мы инлайн -> адрес переменной должен быть такой же как и у вызываемой ф-ции
}
void test_f()
{
char test;
is_inline_f(test, &test);
}
Сам не тестил, лень
Re[2]: Как узнать в рантайме была ли заинлайнена функция?
Здравствуйте, saf_e, Вы писали:
__>Теоретически можно попробовать что-то вроде:
Как только ты берёшь адрес у переменной, ты приземляешь её в стек.
По стандарту, адреса разных переменных (у вызывающей функции и внутри вызываемой), чьи времена жизни перекрываются, должны различаться. Даже если эти переменные нигде больше не используются.
(Мне так кааэтся).
Перекуём баги на фичи!
Re: Как узнать в рантайме была ли заинлайнена функция?
Здравствуйте, denisko, Вы писали:
D>Есть у нас в проекте ручной разворачиватель классов через лямбды, используется он в туевой куче месте в важных с точки зрения производительности местах. Это хозяйство (проект) собирается под разные платформы, соответственно смотреть километровые простыни -Winline под гсс нет никакого желания. Сейчас есть режим работы приложения, когда оно прогоняет на тестовых данных все сомнительные функции и если "оптимизированная версия" медленнее неоптимизированной, то верещит. Прогонять тоже занимает какое то время, поэтому хочется придумать волбешную пилюлю, чтобы съел ее и сразу в момент вызова функции (внешне разворачивалка выглядит как цепочка рекурсивных функций) мог узнать заинлайнилась она или нет? Есть идеи?
Если собирать с отладочными симовлами, то среди символов будут не-заинлайненые функции, а заинлайненых быть не должно.
Можно проверять значение адреса возврата на стеке или значение EBP для стек фрейма, и сравнивать её внутри и снаружи.
В студии есть меджик _ReturnAddress, про который явно сказано
Optimizations such as inlining may affect the return address. For example, if the sample program below is compiled with /Ob1, inline_func will be inlined into the calling function, main. Therefore, the calls to _ReturnAddress from inline_func and main will each produce the same value.
Ну и на других компиляторах можно такое сделать через asm вставки, если интринсика нет.
Мне кажется, лучше, если заработает через символы, т.к. это неинтрузивный путь; asm-вставки могут аффектить инлайнинг.
Русский военный корабль идёт ко дну!
Re[2]: Как узнать в рантайме была ли заинлайнена функция?
Здравствуйте, saf_e, Вы писали:
_>Сам не тестил, лень
Как в квантовой механике — сам факт наблюдения меняет результат.
В твоем случае твой код как раз и приводит к тому что функция может перестать быть inline.
Мой gut feeling (в русской транскрипции "ж***й чувствую") говорит что только анализом логов компайлера или чего-то там это можно узнать надежно...
Re: Как узнать в рантайме была ли заинлайнена функция?
Здравствуйте, denisko, Вы писали:
D>Есть у нас в проекте ручной разворачиватель классов через лямбды, используется он в туевой куче месте в важных с точки зрения производительности местах. Это хозяйство (проект) собирается под разные платформы, соответственно смотреть километровые простыни -Winline под гсс нет никакого желания. Сейчас есть режим работы приложения, когда оно прогоняет на тестовых данных все сомнительные функции и если "оптимизированная версия" медленнее неоптимизированной, то верещит. Прогонять тоже занимает какое то время, поэтому хочется придумать волбешную пилюлю, чтобы съел ее и сразу в момент вызова функции (внешне разворачивалка выглядит как цепочка рекурсивных функций) мог узнать заинлайнилась она или нет? Есть идеи?
Под конкретную платформу можно что-то такое замутить:
Здравствуйте, denisko, Вы писали:
D>Есть у нас в проекте ручной разворачиватель классов через лямбды, используется он в туевой куче месте в важных с точки зрения производительности местах. Это хозяйство (проект) собирается под разные платформы, соответственно смотреть километровые простыни -Winline под гсс нет никакого желания. Сейчас есть режим работы приложения, когда оно прогоняет на тестовых данных все сомнительные функции и если "оптимизированная версия" медленнее неоптимизированной, то верещит. Прогонять тоже занимает какое то время, поэтому хочется придумать волбешную пилюлю, чтобы съел ее и сразу в момент вызова функции (внешне разворачивалка выглядит как цепочка рекурсивных функций) мог узнать заинлайнилась она или нет? Есть идеи?
Во-первых, может быть не только подстановка, но и иное использование в месте вызова знания об определениии функции.
Во-вторых, в одних местах может подставится, а в других -- нет.
Так что вообще не совсем понятно, что конкретно ты хочешь.
IMHO, если ты просто хочешь почитать список варнингов о том, что что-то где-то не подставилось, то проще всего разобрать скриптом лог компиляции...
Только смысл этого всё равно не совсем понятен...
А что такое "ручной разворачиватель классов через лямбды"? Это какой-то кодогенератор? Может его переделать так, что бы сомнений в том, что результат эффективный, не возникало?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Как узнать в рантайме была ли заинлайнена функция?
Здравствуйте, Erop, Вы писали:
E>Во-первых, может быть не только подстановка, но и иное использование в месте вызова знания об определениии функции. E>Во-вторых, в одних местах может подставится, а в других -- нет.
E>Так что вообще не совсем понятно, что конкретно ты хочешь. E>IMHO, если ты просто хочешь почитать список варнингов о том, что что-то где-то не подставилось, то проще всего разобрать скриптом лог компиляции... E>Только смысл этого всё равно не совсем понятен...
Егор не мешай двигаться от русского форума к оплоту демократии.
E>А что такое "ручной разворачиватель классов через лямбды"? Это какой-то кодогенератор? Может его переделать так, что бы сомнений в том, что результат эффективный, не возникало?..
Типа такого http://rsdn.ru/forum/alg/5579882.1
(отсюда, понятно, что вопрос о подстановке где то еще лишен смысла?) с достаточным количеством блекджека и необходимым количеством шлюх, чтобы можно было использовать нескольким людям в проекте. Можно переделать в этом проблемы нет, но тогда отлаживать будет неудобно -- бряку в макрос не забьешь. А так а) удобно б) быстро, если все развернулось правильно с) компактно и читабельно.
<Подпись удалена модератором>
Re[3]: Как узнать в рантайме была ли заинлайнена функция?
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, saf_e, Вы писали:
__>>Теоретически можно попробовать что-то вроде:
К>Как только ты берёшь адрес у переменной, ты приземляешь её в стек. К>По стандарту, адреса разных переменных (у вызывающей функции и внутри вызываемой), чьи времена жизни перекрываются, должны различаться. Даже если эти переменные нигде больше не используются. К>(Мне так кааэтся).
Вот этот тест в VS2013 работает. В дебаге — 0, в релизе — 1. Возможно это только особенность компилятора, которую потом уберут...
inline bool test(char a, char *addr_a)
{
return addr_a == &a;
}
int _tmain(int argc, _TCHAR* argv[])
{
char test_v;
bool v = test(test_v, &test_v);
std::cout << v << std::endl;
}
Re[3]: Как узнать в рантайме была ли заинлайнена функция?
Здравствуйте, denisko, Вы писали:
D>Егор не мешай двигаться от русского форума к оплоту демократии.
Если будет понятно, в чём твой вопрос, будет проще дать тебе хороший совет...
E>>А что такое "ручной разворачиватель классов через лямбды"? Это какой-то кодогенератор? Может его переделать так, что бы сомнений в том, что результат эффективный, не возникало?.. D>Типа такого http://rsdn.ru/forum/alg/5579882.1
(отсюда, понятно, что вопрос о подстановке где то еще лишен смысла?) с достаточным количеством блекджека и необходимым количеством шлюх, чтобы можно было использовать нескольким людям в проекте. Можно переделать в этом проблемы нет, но тогда отлаживать будет неудобно -- бряку в макрос не забьешь. А так а) удобно б) быстро, если все развернулось правильно с) компактно и читабельно.
Речь идёт о "разворачивателе циклов", то есть?
А как ты борешься с тем, что простую функцию в цикле, ну, там удвоение, например, оптимизатор может сделать через SSE, а твой разворачиватель вряд ли? Или твоему компилятору это не мешает?
В любом случае, как это выглядит? Ну, типа пишешь вызов вроде
call_for_range<5, 184>( тут лямбда );
или как-то ещё?
Например, один из путей, завернуть всё в макрос, в котором определять CRTP-наследника класса-механизма этой раворотки, в котором определять тело цикла, которое помечать как force_inline и парсить лог компиялции на тему того, что такой метод не подставился, подойдёт?
То есть будет то-то вроде
STATIC_RANGE_FOR_BEGIN( 5, 184, тут список захватываемых переменных ) {
тут тело цикла;
}STATIC_RANGE_FOR_END;
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Как узнать в рантайме была ли заинлайнена функция?
как по мне так если есть препроцессор, то должен быть и постпроцессор распарси репорт компайлера, сохрани в хмлку и засунь в репку, после изменений проделай тоже самое и чекай дифф, делов то