2013-09-24 3 views
2

В последнем раунде рефакторинга моего кода я заменил кучу классов шаблонов с фиксированным числом аргументов шаблона с переменными аналогами. Я был немного озадачен, узнав, что в конкретном тесте производительности наблюдается снижение производительности около 20-30%.Эффективное влияние вариационных шаблонов

Несколько git bisect roundtrips позже опознавательный фиксатор был идентифицирован. Она в буквальном смысле состоит из одного изменения от

template <typename T, typename U> 
class foo {}; 

в

template <typename T, typename ... Args> 
class foo {}; 

Я экспериментально подтверждено, что применение этого одно изменение вызывает замедление упомянутого выше. Еще более озадачивающе, переключение версии компилятора (от GCC 4.7 до GCC 4.8) переносит замедление на другую аналогичную фиксацию (т. Е. Другой переход от фиксированного к вариационным аргументам, но в другом классе bar).

Чтобы дать немного контекста, этот конкретный тестовый пример производительности представляет собой очень разреженную проблему компьютерной алгебры, которая связана с памятью и, следовательно, очень восприимчива к эффективному использованию кэш-памяти. Этот тестовый случай всегда был проблематичным местом в моем коде (например, вокруг GCC 4.4/4.5 я использовал, чтобы вручную настроить параметры компилятора, управляющие обнаружением размеров строки кэша, чтобы извлечь максимальную производительность).

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

EDIT

Для справки, это обязательство, что восстановить хорошее поведение производительности. К сожалению, он состоит из возврата к невариантному коду для группы классов (а не только одного класса). Я попытаюсь придумать более ограниченный пример.

https://gitorious.org/piranhapp0x/mainline/commit/b952c613b42fe480fe4ed2dfd3e683eb9e38e4cd

+0

Действительно ли это пустой класс? Или просто упрощение? –

+0

@ DavidRodríguez-dribeas: просто упрощение. Я хотел бы пояснить, что единственным изменением был переход на объявление вариационного шаблона. Остальная часть кода остается неизменной и не знает разницы между вариабельными и невариантными версиями класса. – bluescarni

+0

Если остальная часть кода осталась «неизменной», не будет ли это прерываться каждый раз, когда кто-то сказал 'U'? –

ответ

4

Это обширный вопрос и обычный подозреваемый (насколько я понимаю) является рекурсивной обработка переменного числа параметров шаблона в сгенерированном коде.

Необходимо проверить, реализованы ли методы, которые используют параметр вариационного шаблона, таким образом, что рекурсия происходит только во время компиляции, а не во время выполнения. Чтобы дать вам некоторую идею, вы можете посмотреть некоторые примеры, например, this answer of mine. Рекурсия происходит во время компиляции, а реальный код - одношаговая пересылка и расширение.

Несмотря на то, что вы написали, я действительно ожидаю, что вам действительно нужно было адаптировать некоторый код, так как иначе Args никогда не может содержать ничего, кроме одного параметра, и было бы совершенно бессмысленно иметь параметр вариационного шаблона - простите меня, если я 'm wrong;) (Из вашего комментария может возникнуть нечто подобное выше в коде, в котором вы передаете пакет параметров)

+0

Да, извините за редактирование ниндзя. Спасибо за указатель, я кое-что прочитаю. Я почти уверен, что в моем случае не так много рекурсии (я просто пытался избежать размещения аргумента шаблона по умолчанию во всей верхней иерархии моих классов - сделать аргумент по умолчанию в базовом классе и использовать вариатор в верхней части) , но я снова повторю проверку. – bluescarni

Смежные вопросы