Странные проблемы с производительностью.

Автор Тема: Странные проблемы с производительностью.  (Прочитано 32055 раз)

0 Пользователей и 3 Гостей просматривают эту тему.

Оффлайн DebalanceАвтор темы

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Тестирую приложение на базе ObjectARX 2015 в Acad 2016. Собственно программа производит некие геометрические построения, предварительно осуществляя математические вычисления. Вдруг выяснилась некая странная особенность: на этапе выполнения математических вычислений при тестировании на машинах с разной конфигурацией программа затрачивает разное время. Самое непонятное для меня это то, что, например, на машине с более мощным камнем и бОльшим объёмом RAM вычисления выполняются существенно дольше чем на компе с более простой конфигурацией. Если оперировать абсолютными цифрами, то имеем следующее:

Комп1: Core i5-4690, RAM 8Гб - время 3 с.
Комп2: Core i5-6600, RAM 32Гб - время 21 с.

Получается в конкретном случае отличие производительности в семь раз!
Что за хрень!
Для меня очевидно, что дело не железе, но в чём ещё? Может кто сталкивался с подобной проблемой?

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Кофейную гущу покажите.

Оффлайн DebalanceАвтор темы

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Кофейную гущу покажите.
К сожалению это не возможно. Пытаюсь копать в сторону реализованной многопоточности (основные вычисления реализованы в отдельном потоке)...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Если оперировать абсолютными цифрами, то имеем следующее:
Абсолютные цифры - не показатель. Сравнивать нужно усреднённые по нескольким измерениям цифры использованного процессорного времени. А причин по которым такое происходит может быть масса.
1) Разная разрядность Windows/AutoCAD
2) Разные версии Windows
3) Разные входные данные
4) Разный двоичный код arx (например, Debug/Release)
5) Наличие различных антивирусов, которые активно мониторят систему.
6) Наличие параллельных процессов, отнимающих кванты процессорного времени.
7) Обращение к AutoCAD для того, чтобы дать ему возможность реагировать на мышь и т.д., перерисовать индикатор прогресса.
Последний пункт может в десятки раз уменьшить скорость обработки.
Потом непонятно что имеется в виду под математическими вычислениями, используются ли средства ObjectARX в этом расчете...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн DebalanceАвтор темы

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Цитировать
Сравнивать нужно усреднённые по нескольким измерениям цифры...
Не понял, какие цифры я должен сравнивать? А главное, зачем? Если я вижу реальную многократную разницу во времени...
Цитировать
1) Разная разрядность Windows/AutoCAD
Везде x64.
Цитировать
2) Разные версии Windows
Комп 1: Win 10, Комп 2: Win 8.1.
Цитировать
3) Разные входные данные
Тестирование осуществлялось на одном и том же чертеже.
Цитировать
4) Разный двоичный код arx (например, Debug/Release)
Release в обоих случаях.
Цитировать
5) Наличие различных антивирусов, которые активно мониторят систему.
Деактивировал антивирус - то же что и в валенках.
Цитировать
6) Наличие параллельных процессов, отнимающих кванты процессорного времени.
Кроме запущенного AutoCAD - более ничего.
Цитировать
7) Обращение к AutoCAD для того, чтобы дать ему возможность реагировать на мышь и т.д., перерисовать индикатор прогресса. Последний пункт может в десятки раз уменьшить скорость обработки.
Оптимизировал проект и создал тестовый вариант: без диалоговых окон (прогресс-баров и т.п.), аннулировал многопоточность; мышь при запуске не трогал - результат тот же.
Цитировать
Потом непонятно что имеется в виду под математическими вычислениями, используются ли средства ObjectARX в этом расчете...
Проект создан без использования MFC. Основная математика реализована на манипуляциях с данными в stl-контейнерах с небольшим вкраплением бустового функционала. Также используется геометрия AcGe-классов.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Для меня очевидно, что дело не железе, но в чём ещё?
Итак одни и теже машинные коды выполняются на разных машинах. Соотвественно в первую очередь это вопрос железа. Во вторую очередь часть процессорного времени на себя отбирает система. Кстати, время ты засекаешь с момента начала сканирования чертежа? Если да, то возможно еще и вопрос быстродействия винчестера. Если в это время попадает еще и вывод на экран результатов (добавление примитивов), то возможно роль играет и видеокарта. Короче говоря вариантов масса и искать причину тебе.
Я бы порекомендовал измерять процессорное (именно процессорное) время на отдельных этапах работы программы и сравнивал их на двух машинах. Может что-то и выплывет.
Кстати, а версии AutoCAD и SP одинаковые?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн DebalanceАвтор темы

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Кстати, а версии AutoCAD и SP одинаковые?
Да, всё идентичное. Попробую проанализировать бенчмарк железа...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Меня честно говоря тоже очень удивляет разница в производительности в 7 раз. Ну в два раза еще куда ни шло...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Так все-же есть конкретный кусок кода который на тестовых данных дает семикратную разницу, или это только при общем замере?

Оффлайн DebalanceАвтор темы

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
В общем мне удалось локализовать проблему, но она из разряда необъяснимых флуктуаций.
После сравнительного анализа комплексной производительности двух компов, который показал 25%-ое превосходство Компа 2 над Компом 1, я стал тестировать в режиме отладки отдельные участки кода на их быстродействие. Основным предметом моего исследования стали stl-контейнеры, которые я заполнял различными типами данных. Вскоре выяснилась странность в поведении вот такого вектора: std::vector<void*>, который как раз и давал примерно семикратную задержку во времени в момент последовательного его заполнения. Привожу свой тестовый код:
Код - C++ [Выбрать]
  1. boost::timer::cpu_timer Timer1;
  2.  
  3. typedef std::vector<void*> TestVector;
  4. const TestVector::size_type VectorSize = 5000000;
  5.  
  6. TestVector TmpVector;
  7. TmpVector.reserve(VectorSize);
  8. for (TestVector::size_type i = 0; i < VectorSize; i++)
  9. {
  10.         TmpVector.push_back(new double(0.001));
  11. }
  12.  
  13. // Очистка контейнера
  14. BOOST_FOREACH(const TestVector::value_type &TmpVal, TmpVector)
  15. {
  16.         double* tt = (double*) TmpVal;
  17.         delete tt;
  18. }
  19. TmpVector.clear();
  20.  
  21. boost::chrono::duration<double> sec;
  22. sec = boost::chrono::nanoseconds(Timer1.elapsed().user);
  23. Timer1.stop();
  24.  
  25. std::stringstream sst;
  26. sst << boost::format("\nTime: <%f>") % sec.count();
  27. OutputDebugStringA(sst.str().c_str());
В программе я использовал данный тип контейнера как универсальный инструмент для хранения указателей различных типов объектов. И вот, стоит только в этом тестовом коде заменить std::vector<void*> на std::vector<double*> как он начинает выполняться без задержек и укладывается в 0,32 с, в то время как в исходном состоянии этот код на данной машине выполнялся за 2,4 с.
Хочу ещё раз отметить, что такая проблема появилась на этом компе вдруг и совершенно внезапно: раньше всё работало безупречно. Кроме того, я протестировал работу программы ещё на нескольких машинах, включая довольно слабые ноутбуки - везде всё работает без задержек. И ещё, некоторые пользователи конкретно этой программы (по моей просьбе) сообщали мне информацию о её быстродействии. И среди этих сообщений были и такие, в которых время выполнения многократно не совпадало с ожидаемым. Поэтому в какой-то степени я рад, что эта флуктуация произошла на доступной для меня машине.
« Последнее редактирование: 23-01-2016, 18:24:48 от Александр Ривилис »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Вскоре выяснилась странность в поведении вот такого вектора: std::vector<void*>, который как раз и давал примерно семикратную задержку во времени в момент последовательного его заполнения.
Могу предположить в чем причина. Тип данных (double *) по умолчанию указывает на границу двойного слова, тип (void *) на границу байта. Таким образом все операции требуют промежуточного перемещения данных на границу двойного слова. Как-то так. Впрочем, думаю что опциями компилятора можно было бы избавится от этой задержки, но могли бы возникнуть побочные эффекты.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Я полагаю что дело "в глубинных" настройках системы выделения памяти (ее фрагментации) - TmpVector.push_back(new double(0.001)) в зависимости от типа контейнера либо кладет значение в уже подготовленный "реверсом" непрерывный кусок памяти, либо кладет туда-же ссылку на объект - но под сами объекты память не готовилась и видимо для 5000000 точно потребуется несколько "переносов".

Оффлайн DebalanceАвтор темы

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Тема получила продолжение. Указанная выше проблема стала проявляться на Компе1. Опять же возникла она вдруг, чисто при работе над проектом. Теперь я решил потестировать работу со списками (std::list<>). Причем не важно какие данные я там храню (void*, double*, double, char) - тормозит конкретно, как при выполнении push_back, так и при выделении памяти в конструкторе контейнера.
Может действительно какие-то настройки линкера надо подкрутить?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
1. Убедись, что используешь все системные библиотеки в Release и именно те, которые из VC 2012 Update 4 - если у тебя установлен Update 5 - могут быть проблемы.
2. Тестировать производительность в Debug не имеет смысла
3. Попробуй с опцией компилятора /Zp8 и /Zp16 : https://msdn.microsoft.com/en-us/library/xh3e3fd0.aspx
4. Посмотри не используется ли файл подкачки при выделении памяти.
тормозит конкретно, как при выполнении push_back
Ну тут вероятно выделяется память если ты используешь new double(...) и т.п.

так и при выделении памяти в конструкторе контейнера.
А вот это я не понял. В коде у тебя пустой конструктор. Или ты имеешь в виду вот это:
Код - C++ [Выбрать]
  1. TmpVector.reserve(VectorSize);
Ну тогда тут тоже выделение большого куска непрерывной памяти.

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Кстати, похоже v.reserve() + v.push_back() в цикле не эффективно:
http://lemire.me/blog/2012/06/20/do-not-waste-time-with-stl-vectors/
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение