программистское
May. 16th, 2007 01:46 amВсе-таки забавно, насколько использование виртуальных методов убивает скорость. Prefetch queue - наше все.
Скажем, алгоритм обрабатывает большие массивы памяти в цикле, который делает относительно мало работы, а вызывается очень много раз. Итератор цикла - виртуальный метод вспомогательного класса, который вызывает еще пару виртуальных методов, и все они делают очень мало работы. Ничего остального не меняя, делаем эти методы невиртуальными, и алгоритм бежит в пять раз быстрее.
no subject
Date: 2007-05-16 08:48 am (UTC)no subject
Date: 2007-05-16 08:55 am (UTC)Зато если под словом "обрабатывает" предположить, что он на самом деле что-то делает (распространённый случай), а не копирует из одного места в другое или там прибавлят 1, то всё преимущество сведётся на нет.
no subject
Date: 2007-05-16 09:21 am (UTC)no subject
Date: 2007-05-16 09:58 am (UTC)no subject
Date: 2007-05-16 10:02 am (UTC)no subject
Date: 2007-05-16 10:10 am (UTC)no subject
Date: 2007-05-16 05:19 pm (UTC)no subject
Date: 2007-05-16 05:56 pm (UTC)no subject
Date: 2007-05-16 07:04 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2007-05-17 12:29 pm (UTC)Вызов функции - это сохранение/восстановление регистров, параметры в стек, и возможно ломаются оптимизации.
невиртуальные методы компилятор сам превращает в inline
Comparative performance : virtual vs. ordinary methods
Date: 2007-05-16 10:10 am (UTC)no subject
Date: 2007-05-16 10:24 am (UTC)Можно смотреть на это, кстати, не как на дефект языков с virtual dispatch, а как на дефект процессорной архитектуры, которая к нему не приспособлена. Поди, лет 40 назад в наборах команд процессоров команды для поддержки подпрограмм тоже были экзотикой, не говоря уж о поддержке многопроцессности и многопроцессорности. Ничего, появились. Или там векторные операции -- появились в "мэйнстриме" на наших глазах :)
no subject
Date: 2007-05-16 10:34 am (UTC)это дефект языков (а точнее, реализаций — не-табличный кеширующий диспатч можно и для C++ сделать, в принципе), жёстко соптимизированных не там где надо.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2007-05-16 12:12 pm (UTC)If the dynamic types of object which you are calling do not match the static type (i.e., different virtual functions being called) then I would love to see how JVM will inline this. If it is possible to determine that dynamic and static types are the same then any decent C++ compiler will generate a direct function call and will inline it if the function was defined as inline.
(no subject)
From:(no subject)
From: (Anonymous) - Date: 2007-05-16 02:33 pm (UTC) - Expand(no subject)
From:(no subject)
From: (Anonymous) - Date: 2007-05-16 04:41 pm (UTC) - Expand(no subject)
From:(no subject)
From: (Anonymous) - Date: 2007-05-17 10:16 am (UTC) - Expand(no subject)
From:(no subject)
From: (Anonymous) - Date: 2007-05-17 02:04 pm (UTC) - Expand(no subject)
From:(no subject)
From: (Anonymous) - Date: 2007-05-17 02:42 pm (UTC) - Expand(no subject)
From:(no subject)
From:no subject
Date: 2007-05-16 08:23 pm (UTC)(no subject)
From: (Anonymous) - Date: 2007-05-17 10:09 am (UTC) - Expand(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2007-05-16 12:56 pm (UTC)no subject
Date: 2007-05-16 02:08 pm (UTC)Еще часто помогает curiously recurring template pattern.
no subject
Date: 2007-05-16 04:11 pm (UTC)no subject
Date: 2007-05-16 04:13 pm (UTC)no subject
Date: 2007-05-16 04:13 pm (UTC)(no subject)
From:no subject
Date: 2007-05-16 07:11 pm (UTC)по крайней мере с индиректами/непредсказанными переходами можно достаточно легко бороться (не использовать без необходимости), а вот cache incoherency может угробить производительность многопоточного приложения гораздо сильнее и бороться с этим гораздо сложнее :/
no subject
Date: 2007-05-16 08:20 pm (UTC)no subject
Date: 2007-05-16 08:31 pm (UTC)Правда-правда ;);)
Date: 2007-05-16 08:56 pm (UTC)было:
if (obje->type == TYPE_01) ((TYPE01)obje)->CallMethod01();
else if (obje->type == TYPE_02) ((TYPE02)obje)->CallMethod01();
else if (obje->type == TYPE_03) ((TYPE03)obje)->CallMethod01();
стало:
obje->CallMethod();
no subject
Date: 2007-05-17 04:36 am (UTC)no subject
Date: 2007-05-17 08:40 am (UTC)