Я пытаюсь повысить производительность моего алгоритма отслеживания лиц C ++, оптимизируя самые трудоемкие разделы моего кода. Интересно, что 86% всего времени обработки отслеживания расходуется его разделом извлечения признаков. Этот экстрактор объектов берет изображение в качестве входных данных и возвращает вектор объектов в качестве выходных данных. Я выделил средство извлечения функций из трекера в отдельный проект, чтобы написать оптимизированную версию с нуля, и убедился, что формат ввода и вывода и контейнеры совпадают с теми, которые использовались в оригинальном трекере. Вот разбивка итогового времени процесса.
- Оригинальный
3 ms/frame
- Оптимизированная версия
1 ms/frame
Как видно, он должен быть в 3 раза быстрее. Но когда я вставляю новый экстрактор функций в свой трекер, внутри трекера он работает примерно на 2.5 ms/frame
. Я не могу понять, почему внутри трекера он работает медленнее, чем когда он работает как самостоятельный проект?
Но вот улов, который я обнаружил случайно. Если я запускаю трекер и в то же время запускаю другой проект в фоновом режиме, то внезапно экстрактор функций внутри трекера конвергируется в 1 ms/frame
. Но как только я прекращаю фоновый проект, он возвращается к 2.5 ms/frame
. Это происходит как на моем ноутбуке с Ubuntu 16.04, так и на настольном ПК с Windows 10.
В попытке понять такое поведение я использовал системный монитор Ubuntu и заметил следующее относительно всех 8 ядер ЦП.
- Когда я запускаю только экстрактор функций, 7 ядер задействованы примерно на 5%, а одно из ядер задействовано на 100%.
- Когда я вставляю экстрактор функций в трекер и запускаю трекер, все 8 ядер задействованы примерно на 30%.
- Теперь, когда я запускаю трекер и вместе с трекером я запускаю любую другую программу (скажем, автономный экстрактор функций), из всех ядер, задействованных на 30%, каждый перепрыгивает на 100%, что может объяснить повышение производительности, которое я получаю в трекере в результате.
Данные свидетельствуют о том, что для того, чтобы экстрактор функций работал с максимальным потенциалом 1 ms/frame
, по крайней мере, одно из ядер должно быть задействовано на 100%. Мой вопрос: как я могу это сделать?