Название: Большие тормоза из-за QVector? Отправлено: qtkoder777 от Январь 18, 2018, 17:52 В функции производится около 4000 вставок в конец QVector. Реализуется линейный алгоритм построения полигональной сетки.
Даже если увеличим число операций в 100 раз, не понимаю как 400000 операций могут выполняться 1.5 секунды на проце 2.5 ГГц. Может ли это быть из-за выделения памяти при каждой вставке в конец? Раньше как то у меня были тормоза из-за структур вида QVector<QVector<T>>, что в принципе имеет место и здесь. С чем это связано? Вставляются такие классы: Код
Название: Re: Большие тормоза из-за QVector? Отправлено: Apktyc от Январь 18, 2018, 18:06 Если количество вставок известно, QVector::reserve() (http://doc.qt.io/qt-5/qvector.html#reserve) вам в помощь.
А может присмотреться к списку? Название: Re: Большие тормоза из-за QVector? Отправлено: Old от Январь 18, 2018, 18:07 Может ли это быть из-за выделения памяти при каждой вставке в конец? Именно из-за этого, множественные переаллокации и копирования.Как правило, вы знаете сколько элементов нужно будет добавить в вектор, резервируйте место сразу. Название: Re: Большие тормоза из-за QVector? Отправлено: Old от Январь 18, 2018, 18:08 А может присмотреться к списку? Вы имеете ввиду QList (там тоже самое), или честный X-связный список?Название: Re: Большие тормоза из-за QVector? Отправлено: Apktyc от Январь 18, 2018, 18:48 Вы имеете ввиду QList (там тоже самое), или честный X-связный список? Прочел, задумался, узнал про QLinkedList, просветился. ;DНазвание: Re: Большие тормоза из-за QVector? Отправлено: __Heaven__ от Январь 18, 2018, 19:02 Я бы ещё присмотрелся к map (или set)
при этом QVector<double> сменил бы на struct MyVector{double x, y, z} а в Edge заменил бы тип p1 и p2 на map::const_iterator для чего нужны mid, e1, e2 - не понял Название: Re: Большие тормоза из-за QVector? Отправлено: qtkoder777 от Январь 18, 2018, 21:55 Я бы ещё присмотрелся к map (или set) Проводится рекурсивное разделение треугольников на 4 части. mid - номер точки середины ребра, e1, e2 - номера рёбер, получаемых при делении данного. при этом QVector<double> сменил бы на struct MyVector{double x, y, z} а в Edge заменил бы тип p1 и p2 на map::const_iterator для чего нужны mid, e1, e2 - не понял Надо избежать повторного добавления точек деления у соседних треугольников. Раньше это и было сделано с помощью QMap<начало ребра, конец ребра, середина>. Сначала грешил на map, так как это C*log(n) к сложности. Переделал без map, а тормоза остались. Название: Re: Большие тормоза из-за QVector? Отправлено: Igors от Январь 19, 2018, 09:14 Надо избежать повторного добавления точек деления у соседних треугольников. В этом есть смысл если есть фейсы (индексы) которых в приведенном коде не видно. Тогда структуры примерно такиеКод Ну и дальше все очевидно: проходитесь по исходным фейсам, строите контейнер ребер и вписываете их индексы в m_edges. Потребуется мапа о которой потом можно забыть. Потом добавляете новые вертексы (по числу ребер) и выдаете на гора новые фейсы и вертексы Название: Re: Большие тормоза из-за QVector? Отправлено: __Heaven__ от Январь 19, 2018, 12:33 Под linux можно ещё попробовать запустить профилирование в callgrind. Делается это через интерфейс qtcreator и результаты удобно выводится. Там и можно глянуть, что тормозит. Может это вообще не Vertex и QVector :)
Название: Re: Большие тормоза из-за QVector? Отправлено: Racheengel от Январь 19, 2018, 15:47 QVector медленный, на винде раза в 2-3 медленней, чем std::vector.
Эта проблема известна (есть тикеты на Qt-Bugs), может быть, в 6-й версии починят. Название: Re: Большие тормоза из-за QVector? Отправлено: Igors от Январь 19, 2018, 16:48 Эта проблема известна (есть тикеты ... Как быстро все "обрастает легендами" :) Я знаю эту задачу, поверьте, какие-то нюансы контейнеров здесь ну совершенно ни при чем. Нужно заниматься алгоритмом (а не синтаксическим сахарином)Название: Re: Большие тормоза из-за QVector? Отправлено: Авварон от Январь 19, 2018, 18:42 QVector медленный, на винде раза в 2-3 медленней, чем std::vector. Эта проблема известна (есть тикеты на Qt-Bugs), может быть, в 6-й версии починят. Ссылку в студию Название: Re: Большие тормоза из-за QVector? Отправлено: Racheengel от Январь 23, 2018, 11:46 https://bugreports.qt.io/browse/QTBUG-44683
https://bugreports.qt.io/browse/QTBUG-44566 https://bugreports.qt.io/browse/QTBUG-49250 Проблема реальная, сами с таким столкнулись. После того, как сменили QVector на std::vector - сильно возрос performance. Конечно, алгоритмических проблем это не решит, но в любом случае не повредит. Название: Re: Большие тормоза из-за QVector? Отправлено: Авварон от Январь 23, 2018, 15:17 Ну половина тикетов из-за неумения пользоваться qvector, например неконстантный operator[] вместо at() или const версии (он детачит контейнер).
А так, надеюсь в qt6 закопают cow и не потому что использовать сложнее, а потому что qvector не умеет хранить move-only типы. Название: Re: Большие тормоза из-за QVector? Отправлено: qtkoder777 от Январь 29, 2018, 11:36 Эта проблема известна (есть тикеты ... Как быстро все "обрастает легендами" :) Я знаю эту задачу, поверьте, какие-то нюансы контейнеров здесь ну совершенно ни при чем. Нужно заниматься алгоритмом (а не синтаксическим сахарином)Вектор реально тормозит. Избавление от push-ей сократило время раз в 15. Чисто переписать полученые 2000-3000 треугольников в массив для рисования занимает 30 мс. Вот и что с этим делать? Название: Re: Большие тормоза из-за QVector? Отправлено: Old от Январь 29, 2018, 11:56 Вектор реально тормозит. Скорее это называется "неправильное использование вектора".Если вы знаете, как устроен вектор, то никогда не будете расширять его по-элементно. Он для этого не предназначен, несмотря на то, что такая возможность есть. Название: Re: Большие тормоза из-за QVector? Отправлено: Авварон от Январь 29, 2018, 14:17 Эта проблема известна (есть тикеты ... Как быстро все "обрастает легендами" :) Я знаю эту задачу, поверьте, какие-то нюансы контейнеров здесь ну совершенно ни при чем. Нужно заниматься алгоритмом (а не синтаксическим сахарином)Вектор реально тормозит. Избавление от push-ей сократило время раз в 15. Чисто переписать полученые 2000-3000 треугольников в массив для рисования занимает 30 мс. Вот и что с этим делать? Ну и опять же проблема не в тормозах, а в функционале - отсутствие range insert. Его кстати ничего не мешает добавить Название: Re: Большие тормоза из-за QVector? Отправлено: Igors от Январь 29, 2018, 14:41 Вектор реально тормозит. Избавление от push-ей сократило время раз в 15. Там на каждой итерации всего 2 resize (один для вертексов, др для фейсов). Наведите порядок в структурах и алгоритме, все за полчаса ляжет. Схемка выше, если что неясно - спрашивайте, попробую помочь Чисто переписать полученые 2000-3000 треугольников в массив для рисования занимает 30 мс. Вот и что с этим делать? Название: Re: Большие тормоза из-за QVector? Отправлено: qtkoder777 от Январь 30, 2018, 14:41 Надо избежать повторного добавления точек деления у соседних треугольников. В этом есть смысл если есть фейсы (индексы) которых в приведенном коде не видно. Тогда структуры примерно такиеКод Ну и дальше все очевидно: проходитесь по исходным фейсам, строите контейнер ребер и вписываете их индексы в m_iEdges. Потребуется мапа о которой потом можно забыть. Потом добавляете новые вертексы (по числу ребер) и выдаете на гора новые фейсы и вертексы Делаю несколько иначе, зато мапы нет. Функция IsVisible замедляет, но не радикально. Если дробить все фейсы без проверки тоже медленно. Все вектора зарезервированы заранее. Что в этом алгоритме не так? Код
Название: Re: Большие тормоза из-за QVector? Отправлено: Igors от Январь 31, 2018, 12:31 Делаю несколько иначе, зато мапы нет. Функция IsVisible замедляет, но не радикально. Если дробить все фейсы без проверки тоже медленно. Все вектора зарезервированы заранее. Что в этом алгоритме не так? Ну неплохо бы сформулировать задачу, хотя бы кратко, чтобы не приходилось о ней догадываться по фрагментам кода :) Насколько я понял, у Вас бессмертная "отсечка по фрустуму", т.е. хотите отбросить полигоны что камера не видит напрямую. Если так, то нужно выжать макс скорости - и зачем чего-то делить, создавать новые вертексы? Просто если тр-к видим - оставляем его, иначе удаляем, всех делов на 5 минут. Не нужно даже создавать второй контейнер, просто перемещаем видимые в начало и выдаем их число для отрисовки. Если же по каким-то причинам (мне неизвестным) все-таки нужно рэзать, то: Здесь точно порылась собака Код Если есть frustum, то eye избыточен, а что делает r (и что за "проецирование на сферу") - не понял. Фрустум делит каждое ребро создавая на нем 0, 1 или 2 новых вертекса. Поэтому Edge лучше нарисовать так Код На этапе предрасчета все равно надо построить все ребра и вписать их индексы в фейсы как говорилось выше. Отсечка под конкретный фрустум сводится к проходу по всем ребрам: если ребро пересекает фрустум, то создаем новые вертексы (1 или 2) и вписываем их индексы в p3 и p4. После этого проходим по всем тр-кам и строим новые - у нас для этого все есть. Название: Re: Большие тормоза из-за QVector? Отправлено: qtkoder777 от Январь 31, 2018, 13:08 Делаю несколько иначе, зато мапы нет. Функция IsVisible замедляет, но не радикально. Если дробить все фейсы без проверки тоже медленно. Все вектора зарезервированы заранее. Что в этом алгоритме не так? Ну неплохо бы сформулировать задачу, хотя бы кратко, чтобы не приходилось о ней догадываться по фрагментам кода :) Насколько я понял, у Вас бессмертная "отсечка по фрустуму", т.е. хотите отбросить полигоны что камера не видит напрямую. Если так, то нужно выжать макс скорости - и зачем чего-то делить, создавать новые вертексы? Задача нарисовать планету. Сначала строится меш для шара, разбивая икосаэдр, потом к вершинам применяется карта высот из текстуры. Получается планета с горами. Отсекаю по фрустуму и по касательному конусу с помощью ограничивающих сфер. (https://image.ibb.co/fcUNb6/img.jpg) (https://imgbb.com/) Вот зачем оператор сравнения рёбер так и не понял. Название: Re: Большие тормоза из-за QVector? Отправлено: Igors от Январь 31, 2018, 14:44 Отсекаю по фрустуму и по касательному конусу с помощью ограничивающих сфер. На всякий случай напомню что в обоих случаях если даже оба вертекса ребра невидимы - это еще ничего не значит, ребро может пересекать как фрустум, так и конус. Поэтому проверка на конус выглядит избыточной. Также есть мерзкий частный случай - ни одно ребро тр-ка не пересекает фрустум, но часть тр-ка все-таки видима (ну как бы тр-к насажен на угол фрустума)Вот зачем оператор сравнения рёбер так и не понял. В любом случае если резать - все начинается с построения ребер, напр такКод Лучше хранить в фейсе p[3] и e[3] [off]Да, а что ж такая тишина? Ведь совсем недавно подробности QVector обсуждались весьма охотно (хотя они здесь как корове седло). А вот содержательная часть почему-то никакого интереса не вызыват :)[/off] Название: Re: Большие тормоза из-за QVector? Отправлено: qtkoder777 от Январь 31, 2018, 15:13 На всякий случай напомню что в обоих случаях если даже оба вертекса ребра невидимы - это еще ничего не значит, ребро может пересекать как фрустум, так и конус. Поэтому проверка на конус выглядит избыточной. Также есть мерзкий частный случай - ни одно ребро тр-ка не пересекает фрустум, но часть тр-ка все-таки видима (ну как бы тр-к насажен на угол фрустума) Проверяется попадает ли во фрустум и конус описанный вокруг треугольника шар. А в этот шар попадут и все треугольники, на которые мы его можем раздробить. Будут некоторые лишние фейсы - по краям фрустума, ну и пусть рисуются. Проверка на конус предотвращает расчет треугольников-антиподов.Сейчас думаю что дело в Vector3D. Каждый раз когда создаётся временный Vector3D, создаются же и все функции-члены, а их много. То есть для производительности придётся переписывать в процедурном стиле? Название: Re: Большие тормоза из-за QVector? Отправлено: Igors от Февраль 01, 2018, 05:41 Ага, ну вроде так: Вы хотите делать триангуляцию только для тех фейсов что прошли тест Visible. Причем хотите делать 2 триангуляции за 1 проход (т.е. фактически тр-ки делятся на 4 * 4 = 16 новых). Все ли я верно понял?
Сейчас думаю что дело в Vector3D. Нет. Инициализируются только данные что этого требуют (здесь конкретно 3 флота x, y, z) - и все. А сколько ф-ций членов (хоть тыщи) никак на производительность не влияет. Каждый раз когда создаётся временный Vector3D, создаются же и все функции-члены, а их много. То есть для производительности придётся переписывать в процедурном стиле? Название: Re: Большие тормоза из-за QVector? Отправлено: Авварон от Февраль 01, 2018, 20:46 Господи, ну есть же десятки профилировщиков.
Название: Re: Большие тормоза из-за QVector? Отправлено: Igors от Февраль 02, 2018, 12:38 Забегая чуть вперед: можно хорошо выжать, даже подключить все ядра, но все-таки для real-time нужна реализация на GPU, Но там такой геморрой :'(
|