Функция Visual C ++ неожиданно замедляется на 170 мс (в 4 раза дольше) - PullRequest
3 голосов
/ 15 июня 2010

Последние несколько месяцев я работал над проектом Visual C ++, чтобы получать изображения с камер и обрабатывать их.До сегодняшнего дня это занимало около 65 мс для обновления данных, но теперь оно внезапно значительно увеличилось.Происходит следующее: я запускаю свою программу и в течение примерно 30 итераций она работает, как и ожидалось, затем внезапно время цикла увеличивается с 65 мс до 250 мс.

Странно то, что после синхронизации каждой функции Iобнаружил, что часть кода, которая вызывает замедление, является довольно простой и не изменялась более месяца.Данные, поступающие в него, остаются неизменными и идентичны на каждой итерации, но время выполнения, которое первоначально составляет менее 1 мс, внезапно увеличивается до 170 мс, в то время как остальная часть кода все еще работает как ожидалось (по времени).

По сути, я вызываю одну и ту же функцию снова и снова, потому что первые 30 вызовов она выполняет должным образом, после чего она замедляется без видимой причины.Также стоит отметить, что это внезапное изменение времени выполнения, а не постепенное увеличение.

Что может быть причиной этого?В коде происходит утечка памяти (~ 50 кбит / с), но этого недостаточно, чтобы обеспечить внезапное 4-кратное замедление.Если у кого-нибудь есть идеи, я бы с удовольствием их услышал!

Редактировать: Вау, это было быстро!Вот код (без математики), который замедляется.Я знаю, что это функция, где вычислительное время будет быстро увеличиваться, если вы увеличите количество строк.Ключевым моментом здесь является то, что с теми же данными это замедляется после 30 итераций.

void CameraManager::IntersectLines()
{

    // Two custom classes
    TMaths maths;
    TLine line1, line2;

    while(lines.size()>0)
    {

        // Save the current line
        line1 = lines[0];

        // Then remove it from the list
        lines.erase(lines.begin());

        CvMat* aPoint;
        for (int i = 0; i<lines.size(); i++)
        {

            line2 = lines[i];

            aPoint = cvCreateMat(1, 4, CV_32FC1);

            // Calculate the point of intersection
            maths.Intersect(line1.xyz, line2.xyz, line1.uvw, line2.uvw, aPoint);

            // Add the point to the list
            points.push_back(aPoint);
            }

        }

    }

}

Ответы [ 7 ]

9 голосов
/ 15 июня 2010

Возможно ли, что после утечки определенного объема памяти ваш компьютер должен начать вводить / выводить данные? Это определенно замедлит даже простые функции.

Не зная, что делает эта функция, трудно сказать точно, что может быть причиной проблемы.

Редактировать: Как предлагается в комментариях к вопросу, утечка определенного объема памяти может также начать выбивать вещи из кэша ЦП, что также замедляет работу. Либо исправление утечки памяти, либо размещение кода здесь, чтобы мы могли на него посмотреть, было бы хорошей идеей.

Редактировать 2: Вы вызываете несколько функций в этом цикле. Они делают что-то кроме простых арифметических вычислений?

5 голосов
/ 15 июня 2010

Если утечка памяти достаточна для заполнения страницы (может быть достаточно 50 КБ / с), то Windows придется переключать страницы для обработки данных. Когда это происходит, программа становится гораздо более неэффективной.

2 голосов
/ 15 июня 2010

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

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

[Редактировать] Я предполагаю, что ваша функция cvCreateMat выделяет некоторую память? Разве это когда-нибудь освобождается?

2 голосов
/ 15 июня 2010

Очевидно, что-то изменилось.Попробуйте вернуть код к тому, что было до замедления.Если это снова быстро, сфокусируйтесь на изменениях кода.Если это медленно, то ищите проблему за пределами вашего кода.Такие вещи, как база данных, ОС и т. Д.

1 голос
/ 15 июня 2010

Профилируйте код , тогда вам не нужно будет угадывать ответы.

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

(Согласно текущему топовому ответу на этот вопрос: Профилирование в Visual Studio 2008 PRO для использования встроенного профилировщика вам понадобится «Team» версия VS 2008, в противном случае вам потребуется использовать внешний профилировщик)

1 голос
/ 15 июня 2010

Вам нужно , чтобы стереть каждую строку в контейнере?

    // Then remove it from the list
    lines.erase(lines.begin());

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

0 голосов
/ 15 июня 2010

Вы должны сделать свой вопрос более конкретным, если хотите получить полезные ответы.

...