Просмотр сообщений
|
Страниц: 1 ... 3 4 [5] 6
|
62
|
Программирование / Общий / Re: STL-compatible контейнеры с семантикой Qt's Implicit Sharing
|
: Октябрь 24, 2020, 16:20
|
Разумеется, иначе что это за контейнер, которой кладет на заданное выравнивание типа. Он волен нижнюю границу поднять (например, минимум 16 байт) из-за каких-то своих соображений, но опустить - никак. Также и нижележащие malloc/realloc не опускаются ниже определенной величины. Собственно, если нужно иметь выровненный буфер как таковой, хранящийся в векторе, то достаточно как-то так: class alignas(256) CacheLine { public: CacheLine(char data = 0) : data_(data) {} operator char() { return data_; }
private: char data_; };
QVector<CacheLine> v; v.push_back({}); qDebug() << (void*)&v.front(); // выровнен на 256 байт
Но работать с ним поэлементно через интерфейс QVector нельзя: v[1] вернет 257 байт, а не второй. Для поэлементной работы с байтами можно грубо пропатчить индексный доступ, но тут уже семантические нарушения по типу: template <typename T> class MyVector : protected QVector<T> { public: T& operator[](int index) { return reinterpret_cast<char*>(QVector<T>::data())[index]; } ... и так далее для всего, ... итераторов };
Это все костыли. Нужно просто, чтобы у QVector был аллокатор. Кстати, как думаете - почему его нет? Полагаю, что Qt-контейнеры создавались прежде всего для собственных нужд (типа хранить чилдренов, небольшой мапчик/хэшик и т.п.), где аллокаторы не нужны.
|
|
|
63
|
Программирование / Общий / STL-compatible контейнеры с семантикой Qt's Implicit Sharing
|
: Октябрь 23, 2020, 14:07
|
Ревизирую старый код, и стоит вопрос рефакторинга QVector->std::vector (также рассматривается std::array для некоторых случаев). Мотивация - иметь выровненные данные в контейнере для последующей оптимизации (векторизации, и в этой связи также рассматривается замена double -> float). Основная семантическая проблема - использование в QVector Implicit Sharing (copy-on-write) при передаче данных, в основном, между потоками. Собственно, вопрос - нужен stl::vector c Implicit Sharing семантикой, в идеале - совместимой с Qt, т.е.: stl::vector v; QVector qv; v = qv; // inc ref. count, not a deep copy
Порекомендуйте хорошие порты STL или просто отдельные библиотеки STL-контейнеров, наделенные данным свойством.
|
|
|
65
|
Qt / Общие вопросы / Re: Корутины (модное слово)
|
: Октябрь 19, 2020, 23:26
|
По-моему другая крайность - недооценка. Возможно, лет через 5 увидим. Драг бы делал на событиях. Собственно, у нас событийная модель программирования, а вы переходите опять к последовательной, в которой эти события все равно должны обрабатываться по ходу последовательности. processEvents(): навскидку, нужно запилить свой эвент диспатчер (наследник QAbstractEventDispatcher), который будет иметь режим извлечения и обработки событий поштучно, т.е. QAbstractEventDispatcher::processEvents() будет извлекать одно событие и возвращать управление. По MouseRelease будет возможность завершить драг перед обработкой последующих событий, например, Esc keypress, которое в противном случае отменило бы завершившийся драг.
|
|
|
66
|
Qt / Кладовая готовых решений / Re: ThreadControl suspend/resume/abort
|
: Октябрь 19, 2020, 22:55
|
Некросплатформенно, это Win API. Я привел пример, когда постановка потока на паузу оправдана, более того, этот функционал есть в Win API, системы, над которой работало не самое малое количество далеко не самых последних инженеров, - согласитесь, это имеет вес.
Скорость переключения? Cерьезно?.. ~ 2000 аccемблерных инструкций на x86 (переход в режим ядра), то же, что и у Sleep.
|
|
|
67
|
Qt / Кладовая готовых решений / Re: ThreadControl suspend/resume/abort
|
: Октябрь 18, 2020, 20:37
|
Ну, например, в Win API есть ref-counted SuspendThread/ResumeThread. Элементарный юзкейс - например, вычисляете 10-ю потоками некое сложное значение, юзер ждет, но решает поставить операцию на паузу и выполнить другое жирное вычисление.
Т.е. такие функции (заметьте, они со счетчиком, и могут быть заюзаны из разных потоков) избавляют от замусоливания рабочего кода всякими проверками флагов паузы.
|
|
|
69
|
Qt / Кладовая готовых решений / Re: SharedHash/Set
|
: Октябрь 18, 2020, 20:09
|
Сто раз обсуждали, но давайте еще: 1. QtContainers требуют T(), что заставляет делать null state у T (QString::isNull/isEmpty), что не для любого T имеет смысл. 2. QtContainers требуют T(const T&). Хотите положить unique_ptr в вектор? забудьте. 3. QtContainers не имеют emplace* методов. Если не юзать pimpl то append(T&&) может быть более затратным (каждый мембер же надо мувнуть). Впрочем, это мелочь. 4. QtContainers не имеют range_insert методов. Хотите быстро вставить в вектор, не двигая полвектора на каждый элемент? Пишите руками. 5. QtContainers любят детачить в рандомных местах, что заставляют писать boilerplate код с qAsConst/временными переменными. Поглядите как "умело" обращаются с ними сами кутешники: https://codereview.qt-project.org/#/c/253792/ Куча таких мест делала дип-копию контейнера. Ухху! 6. QtContainers медленее за счет лишнего разыменования d_ptr. Это в Qt6 пофиксят, правда. 7. QtContainers медленее за счет постоянной проверки refcount, даже когда идет append в цикле. 8. QtContainers генерят больше бинарного кода: https://codereview.qt-project.org/#/c/261870/9. QMap/QHash нельзя итерировать в range-for по ключу-значению, что либо заставляет писать говнокод с итераторами, либо говнокод с .keys() и последующим .value(). Ухху! Для некоторых алгоритмов фатальный недостаток QtContainers - нет возможности выравнивания данных (нет аллокатора, идущего параметром шаблона в контейнерах stl).
|
|
|
70
|
Qt / Общие вопросы / Re: Корутины (модное слово)
|
: Октябрь 18, 2020, 18:15
|
Как уже здесь многие отмечали, концепции этой "корутины" уже сто лет в обед. Мейнстрим практика - например, в Win32 API, начиная с NT 3.51, есть функция CreateFiber (читай корутина), которая в свою очередь создавалась с целью облегчения портирования Unix-овых программ под Windows. Соответственно, в Unix-ах это API появилось ... даже не знаю когда.
Востребованность? А часто ли требуется ручное переключение контекста? Часто ли вы использовали setjump/longjump? Ну если только вы пишите специфичный инструментарий, манипулирующий контекстом, например, такой как обработка исключений (есть разные реализации, в т.ч. через setjump/longjump).
|
|
|
71
|
Qt / Общие вопросы / Re: Сравнение с QVariant
|
: Июль 12, 2020, 08:28
|
template<class T> bool SameValue( const QVariant & v, const T & value ) { return v.canConvert<T>(value) && (v.value<T>() == value); }
|
|
|
72
|
Qt / 2D и 3D графика / Re: Qt Charts и Qt Data Visualization — кто-нибудь пользовался?
|
: Июль 11, 2020, 00:17
|
Подниму тему - как сейчас обстоят дела Qwt vs Qt Charts vs QCustomPlot vs ...? Доработан ли Qt Charts для комфортного использования ран-тайм отрисовки графиков (например, сигнал со звуковухи)?
От себя добавлю - в 2016 довольно основательно выбирал Qt-friendly библиотеку для отрисовки 2D реал-тайм графики (сигналы, спектрограммы и т.п.), да и всякие контролы типа потенциометров тоже были весьма желательны. Qt Charts тогда было платно, малофункционально и, как я тогда предположил, не слишком шустро для рантайм отрисовки. QCustomPlot интерфейсом был неплох, но серьезно проигрывал Qwt в быстродействии - там при просмотре исходников это сразу стало понятно. Чего то другого стоящего не нашел, поэтому выбор пал на Qwt.
Qwt, в принципе, меня удовлетворила. Имеет продуманный объектный дизайн, допускающий широкую кастомизацию (чуть ли не каждый объект в итоговом композите, например, таком как QwtPlot, можно заменить кастомным), код весьма качественный. Документация - средняя. Примеры базового использования в комплекте (большой плюс). Есть поддержка от самого автора, отвечает оперативно и предметно даже на вопросы типа "А как мне сделать так-то и так-то". На баги - еще быстрее.
В плане быстродействия либа не слишком оптимизирована, - например, для получения каждой точки отрисовываемой кривой вызывается виртуальная функция, но эта плата за абстракцию и функциональность (в плане расширения). Если провести сравнительную параллель - то это как если бы в STL был базовый класс контейнера с виртуальными/абстрактными функциями-членами типа operator[] и абстрактными итераторами, и std::vector наследовался бы от этого базового контейнера.
Однако, после небольшой собственной оптимизации (QwtPlotOptimizedCurve) в купе с кастомными QwtSeriesData, QwtRasterData и т.п., берущими данные из циклических буферов, получил приемлемую скорость рантайм отрисовки (обновление с частотой ~10-20 Гц - большей глазу и не нужно) даже на ARM v7 linux-девайсах. Каких-то серьезных багов не обнаружил, утечек памяти - тоже (специально не искал, но сутками работающее приложение оставалось с тем же потреблением). Так что ставлю Qwt 4 из 5 - из-за неоптимизированности для ран-тайм отрисовки и местами скудноватой документации.
|
|
|
73
|
Qt / Qt-инструментарий / Re: Shadow build в MSVC IDE
|
: Июль 02, 2020, 22:43
|
Друзья, все так, спасибо!
Студия с аддоном уже при открытии pro-файла замусоривает сорцы.
ИМХО, если в pro-файле задавать выходные папки сборки, то там должны быть только относительные пути (относительно корня проекта), чтобы было максимально портабельно.
|
|
|
74
|
Qt / Qt-инструментарий / Shadow build в MSVC IDE
|
: Июль 02, 2020, 11:49
|
В Qt проекте, который собирается из QtCreator или из ком. стороки, используется теневая сборка, т.е. вне папки исходников. Для использования MSVC его solution генерируется так: qmake -tp vc -r CONFIG+=release При этом сборка из MSVC IDE происходит в папке исходников. Как задействовать теневую сборку, чтобы не править вручную сгененрированные файлы проекта MSVC, в идеале - задать теневую сборку в ком. строке вызова qmake выше? В принципе, запуск qmake из другой директории, поддиректории, например, частично решает проблему: qmake -tp vc -r CONFIG+=release ..\MyProject.pro Сорцы, находящиеся в папке ..\src не засоряются.
|
|
|
|
|