Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
Имею консольную программу (хотя это еще вопрос, кто кого имеет :) ), выполняющую математические вычисления над структурами с данными. Каждая структура содержит массивы связей с другими структурами типа vector<Tn>. Четыре типа структур: T1 - 26шт, T2 - 100 шт, T3 - 3 шт, T4 - 1 шт: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. Вычисление проводится последовательным перебором структур: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. И вот, в чем проблема - аналогичная модель работает в аналогичной программе в C# почти в два раза быстрее, чем в C++!!! Хотелось бы понять, почему так происходит. Я начал навешивать счетчики на функции Activate и выяснил, что суммарно Activate(T4* arg) работает 22 сек, Activate(T3* arg) 13 сек, а Activate(T1* arg) работает 11 сек. Если учесть, что Activate(T1* arg) производит все вычисления, а Activate(T4* arg) и Activate(T3* arg) ничего посути не делают, кроме перебора элементов вектора и карты, то проблема в скорости доступа к элементам массива (вектора и карты) либо потери на вызове функции. Но это нонсенс - вектора должны работать быстро, а вызовы не могут так сильно тормозить. Либо я что-то упускаю из виду, либо неверно вектора использую (про карту вообще молчу - там 3 элемента и самая большая потеря по времени). Что думаете? Я ожидаю, что программа на С++ должна работать в два раза быстрее С#, а пока получается наоборот. Нужно решить эту проблему, прежде чем двигаться дальше. Пока идеи такие: навешать аналогичные счетчики на clr-сборку C# и сравнить результаты. Поиграться с директивами методов: использовать что-то типа __fastcall Заменить массивы на простой array[] Покопаться в настройках компилятора: может собрать exe-типа релис или еще что-то Накидывайте идеи, буду пробовать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 09:36 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybs, Приведите полный код программы. Ключи компилятора которые используете. Так же в вашем случае в виду всего лишь трех элементов это малозначимно, но map != Dictionary. map - O(log n) Dictionary - O(const) Нужен весь код, по приведенному участку не видно где может быть затык. Кстати поток-то один? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 09:54 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
sherzod_andreybs, Приведите полный код программы. Ключи компилятора которые используете. Так же в вашем случае в виду всего лишь трех элементов это малозначимно, но map != Dictionary. map - O(log n) Dictionary - O(const) Нужен весь код, по приведенному участку не видно где может быть затык. Кстати поток-то один? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. вот примерное определение структур: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. замеряем скорость так: Код: plaintext 1. 2. Проект собран на базе MS Visio 2012, как консольное приложение с дефалтовыми настройками. Настройки: [C++] /Yu"stdafx.h" /GS /analyze- /W3 /Zc:wchar_t /ZI /Gm /Od /Fd"Debug\vc110.pdb" /fp:precise /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\NeuroNet.pch" [Компилятор] /OUT:"D:\Private\Mongoose3\Projects\Console\NeuroNet\Debug\NeuroNet.exe" /MANIFEST /NXCOMPAT /PDB:"D:\Private\Mongoose3\Projects\Console\NeuroNet\Debug\NeuroNet.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /INCREMENTAL /PGD:"D:\Private\Mongoose3\Projects\Console\NeuroNet\Debug\NeuroNet.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\NeuroNet.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1 Приложение однопоточное, но в будущем планирую подключить AMP (Accelerated Massive Parallelism). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 11:58 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybs, Пока видно следующее По флагам - стоит дебаг режим (это значительно медленнее), отключена оптимизация /Od, включена проверка границ массивов. Видимо это просто дебаг-конфигурация, добавьте релиз-конфигурацию и в ней замеряйте скорость. По коду - попробуйте заменить std::map на std::unordered_map, используйте префиксный ++ для итераторов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 12:42 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybs, используй Replace Condition With Polimorphysm. Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 12:58 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
maytonandreybs, используй Replace Condition With Polimorphysm. Код: plaintext 1. 2. 3. 4. Обязательно. Вообще я планировал использовать "лямбды". Вот только с производительностью разбирусь... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 14:22 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
Я не знаю практически полезных use-case с лямбдами в С++. Всё тки в С++ надо играть по правилам его использования. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 14:37 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
maytonЯ не знаю практически полезных use-case с лямбдами в С++. Всё тки в С++ надо играть по правилам его использования. Вы серьёзно, не знаете где lambdas могут быть полезны? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 14:43 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
sherzod_andreybs, Пока видно следующее По флагам - стоит дебаг режим (это значительно медленнее), отключена оптимизация /Od, включена проверка границ массивов. Видимо это просто дебаг-конфигурация, добавьте релиз-конфигурацию и в ней замеряйте скорость. По коду - попробуйте заменить std::map на std::unordered_map, используйте префиксный ++ для итераторов. Поигрался с компилятором - релис-конфигурация не помогла. Прирост минорный - 5%. /Yu"stdafx.h" /GS /GL /analyze- /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /Fd"Release\vc110.pdb" /fp:precise /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /Fa"Release\" /EHsc /nologo /Fo"Release\" /Ot /Fp"Release\NeuroNet.pch" Еще попробую немного поиграть с параметрами оптимизации, но похоже дело в коде. Кстати, как отключить проверку границ массивов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 17:09 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybssherzod_andreybs, Пока видно следующее По флагам - стоит дебаг режим (это значительно медленнее), отключена оптимизация /Od, включена проверка границ массивов. Видимо это просто дебаг-конфигурация, добавьте релиз-конфигурацию и в ней замеряйте скорость. По коду - попробуйте заменить std::map на std::unordered_map, используйте префиксный ++ для итераторов. Поигрался с компилятором - релис-конфигурация не помогла. Прирост минорный - 5%. /Yu"stdafx.h" /GS /GL /analyze- /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /Fd"Release\vc110.pdb" /fp:precise /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /Fa"Release\" /EHsc /nologo /Fo"Release\" /Ot /Fp"Release\NeuroNet.pch" Еще попробую немного поиграть с параметрами оптимизации, но похоже дело в коде. Кстати, как отключить проверку границ массивов? Так, сказал глупость... :) Настройки я сменил, а тестил старое приложение. Релис-конфигурация дала просто феерические результаты - 2,140 млн вычислений в секунду. В 28 раз быстрее дебаг-версии! Прям не ожидал, что оно на столько повлияет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 17:29 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
sherzod_По коду - попробуйте заменить std::map на std::unordered_map, используйте префиксный ++ для итераторов. Сделал. Интересное наблюдение - дебаг-версия ускорилась существенно, а релис-версия осталась такой же. Пробовал использовать доступ к элементам unsorted_map через оператор [], но почему то возвращается null, хотя элементы в массиве есть. Так что оставил ++итератор. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 18:54 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
maytonandreybs, используй Replace Condition With Polimorphysm. Код: plaintext 1. 2. 3. 4. Я попробовал простой динамический вызов функции, указатель которой хранится в каждой структуре. Производительность упала на 7%. Если динамический вызов работает медленнее switch, то нет смысла рассматривать полиморфизм и лямбды, т.к. это еще медленнее. Переход от структур к классам нежелателен. Хотя попробовать ради эксперимента можно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 20:01 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybs, Если настолько важна скорость, заинлайньте функции. Они все у вас вызываются в циклах, поэтому выигрыш будет довольно значимый. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.08.2013, 21:28 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
sherzod_andreybs, Если настолько важна скорость, заинлайньте функции. Они все у вас вызываются в циклах, поэтому выигрыш будет довольно значимый. Хорошая мысль, обязательно попробую! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2013, 00:58 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybs, Если в map только три элемента, не лучше ли использовать вектор вместо нее? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2013, 10:45 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
sherzod_andreybs, Если настолько важна скорость, заинлайньте функции. Они все у вас вызываются в циклах, поэтому выигрыш будет довольно значимый. Безуспешно. Даже __forceinline не влияет на производительность. Еще попробовал связанный со структурой полиморфный класс с одной функцией расчета. Быстрее, чем динамический вызов функции по указателю, но прироста в производительности не дал. Зато можно разносить код по разным функциям. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2013, 11:29 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
MasterZivandreybs, Если в map только три элемента, не лучше ли использовать вектор вместо нее? Для производительности может и лучше, а для логики работы - хуже, т.к. присутствует достаточно частое обращение к элементам по id и поиск будет тормозить, если использовать вектор. Но ничто не мешает одновременно использовать вектор и карту. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2013, 11:32 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
Нашел простое и элегантное (на мой взгляд) решение: Код: plaintext 1. 2. 3. 4. 5. Далее обращаемся к F[0](arg), как к F1(arg) без потери производительности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.08.2013, 12:07 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybsMasterZivandreybs, Если в map только три элемента, не лучше ли использовать вектор вместо нее? Для производительности может и лучше, а для логики работы - хуже, т.к. присутствует достаточно частое обращение к элементам по id и поиск будет тормозить, если использовать вектор. Но ничто не мешает одновременно использовать вектор и карту. В трёх элементах? Ну ну. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2013, 10:49 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybsandreybsпропущено... Поигрался с компилятором - релис-конфигурация не помогла. Прирост минорный - 5%. /Yu"stdafx.h" /GS /GL /analyze- /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /Fd"Release\vc110.pdb" /fp:precise /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /Fa"Release\" /EHsc /nologo /Fo"Release\" /Ot /Fp"Release\NeuroNet.pch" Еще попробую немного поиграть с параметрами оптимизации, но похоже дело в коде. Кстати, как отключить проверку границ массивов? Так, сказал глупость... :) Настройки я сменил, а тестил старое приложение. Релис-конфигурация дала просто феерические результаты - 2,140 млн вычислений в секунду. В 28 раз быстрее дебаг-версии! Прям не ожидал, что оно на столько повлияет. Не мудрено, Debug режим вообще ни для чего не предназначен, кроме отладки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2013, 10:53 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybssherzod_По коду - попробуйте заменить std::map на std::unordered_map, используйте префиксный ++ для итераторов. Сделал. Интересное наблюдение - дебаг-версия ускорилась существенно, а релис-версия осталась такой же. Пробовал использовать доступ к элементам unsorted_map через оператор [], но почему то возвращается null, хотя элементы в массиве есть. Так что оставил ++итератор. Скорость debug сборки мерить вообще бессмысленно. Так тебе теперь хватает скорости в релиз сборке? Если нет — сори сборку с профайлером, запусти и погляди, где главный тормоз. Только не мерий ее скорость , и лучше уменьши размерность задачи, что бы программа когда-то кончилась, потому что с профайлером все очень медленно работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2013, 11:03 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybsНашел простое и элегантное (на мой взгляд) решение: Код: plaintext 1. 2. 3. 4. 5. Далее обращаемся к F[0](arg), как к F1(arg) без потери производительности. Копнув глубже в производительность и подсчитав число тиков выяснил, что в приведенном выше примере inline не работает. Оно и понятно - переход ведь по указателю происходит. Поэтому если субколла не удается избежать, то лучше использовать ускоренный вызов (экономит 5% тиков в моем случае): Код: plaintext 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2013, 11:42 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
MasterZivandreybsпропущено... Для производительности может и лучше, а для логики работы - хуже, т.к. присутствует достаточно частое обращение к элементам по id и поиск будет тормозить, если использовать вектор. Но ничто не мешает одновременно использовать вектор и карту. В трёх элементах? Ну ну. Элементов может быть чуть больше и тогда линейный поиск усложнится в разы. А вот для перебора через итератор маленького массива (до 12 элементов) разницы вообще нет. Проверил со счетчиками. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2013, 11:45 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
MasterZivТак тебе теперь хватает скорости в релиз сборке? Теперь хватает. Сейчас я тестирую разные способы организации структуры блока вычислений, чтобы он не проседал при разрастании логики вычислений. Потом попробую параллельные вычисления AMP. А дальше на полученном движке буду решать реальную задачу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2013, 11:49 |
|
||
|
оптимизация производительности консольного приложения
|
|||
|---|---|---|---|
|
#18+
andreybs, а профилировщик что показывает? Есть возможность подгрузить задачу на 1-2 минуты объёмом? Маппинг std::map<int, T3*> можно попробовать заменить на работу с указателями. Всётки мапа больше на целочисленный ID расчитана. А если у тебя всё in-memory то можно где-то "сократить маршрут". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.08.2013, 15:36 |
|
||
|
|

start [/forum/topic.php?fid=57&fpage=73&tid=2020016]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
36ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
75ms |
get tp. blocked users: |
2ms |
| others: | 275ms |
| total: | 432ms |

| 0 / 0 |
