Программирование

Удивительное рядом (о совместимости ABI компиляторов)

Волею судеб тут пришлось делать следующие упражнения:

  • Собрать некую библиотеку (C++) с помощью Visual Studio 2013 тулсетом для XP (Platform toolset: v120_xp) и использовать ее потом из Visual Studio 2010.
  • Собрать некую библиотеку (C++) с помощью Clang (clang-cl, версия 4.0.1) и использовать (вызывать) ее потом из кода, собираемого Visual Studio (в данном случае 2015, но думаю проделать то же с 2010 и 2013). А из clang-собранной библиотеки зовется еще одна, собранная 2015-й студией.

Причина была одна и та же, первая "некая библиотека" не собирается 2010й студией, ибо используемый C++ новее, аналогично и со второй (сходу только Clang/gcc, под MSVC надо править, но очень уж не хотелось).

На удивление, оба варианта проканали вообще без каких-то проблем (я опасался, что придется тянуть всякие чужие C/C++ рантаймы, но нет). Про Clang известно, что над совместимостью по name mangling и подобному там все еще ведутся улучшения, но базовые вещи работают уже.

Еще более на удивление, с clang-cl работают базовые вещи у отладчика VisualStudio (небазовые не пробовал).

Итого: вот просто берешь и используешь (в случае Clang - запускаешь еще батник для интеграции с VS).

Вот что не работает с раздачи, так это cmake, которому указано что используется clang-овский toolset. Оно каким-то чудом узнает, что вот работает clang (хоть и -cl) и пытается совать туда clang-овские же свитчи командной строки, а clang-cl их не понимает. Надо править бы, но я этот ad-hoc язык не знаю и очень не хочу узнавать.

 

Трудовые будни

Кто нибудь может мне объяснить, отчего вот такой вот кусок кода перестал работать в Win10 (в анонс не лезет - перейдите в полный текст :)

Есть многое на свете....

А вот возьмем OS X Sierra. Есть один (то есть единственный) пользователь, на компьютере которого не работает такой вот код:

QString xmpfile = ....; // вычислить имя XMP из имени raw
QFile xmpw(xmpfile);
if (!xmpw.open(QIODevice::WriteOnly)) -> тут обрабатываем ошибку

И ошибка - EACCESS, прав нету

А вот такой вот код работает:

QString xmpfile = ....; // вычислить имя XMP из имени raw
int fd = open(xmpfile.toUtf8().data(), O_WRONLY | O_CREAT | O_TRUNC, 0664);

То есть открывается дескриптор...

Q: про Qt

Граждане, а есть опыт подачи своих патчей в Qt?

Не багфиксов, а расширения функциональности существующих модулей (QDirModel/QFileSystemModel).

Есть смысл куда-то сначала написать (в development?) на предмет "а оно вообще интересно кому-то"?

Я просто опасаюсь потратить на это время - и без результата. Особенно с учетом того, что мы работаем с Qt 5.4, а патчи попадут - если попадут - куда-то в район 5.9

Qt ненависти псто (3)

А вот, значит, еще про Qt.

Допустим, у нас есть QListView (с кастомными элементами, но это в данном случае несущественно). В нем мелко показаны фигульки.

Хотим: при клике на фигульку спрятать QListView и на его месте показать фигульку крупно (в QGraphicsView, хотя это тоже не так и важно).

Первые грабли зарыты в "спрятать-показать". Если запихнуть их, скажем, в один QLayout и делать  QListView->hide(); QGraphicsView->show(), то оно может валится. Не всегда. При некоторых размерах окна. Ну ладно, сначала show/hide, а потом...

Qt MVC: ненависти псто - 2

А вот например Qt. Обычный такой QTableView на две колонки, хочется банального:

  1. Чтобы занимало окошко целиком, даже если строки короткие, иначе там odd/even rows некрасиво.
  2. Чтобы если строки длинные - был бы скроллбар.

Осложняется, правда, тем, что некоторые строки - HTML-ные, то есть их надо руками рендерить. Соответственно, для DisplayRole надо отдавать пустой текст (это я сейчас знаю!), HTML-ку получать другой ролью и рендерить самостоятельно.

И что вы думаете? ДВА ДНЯ. И то, полностью не победил, скроллбар в результате есть всегда. Ну хоть так.

При этом узнал, что SizeHint есть:

  1. В Q...ItemModel::data()
  2. В QTableView::sizeHintForColumn
  3. В QItemDelegate::sizeHint

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

Qt MVC: ненависти псто!

Вот есть такой Qt. А в нем полноценный Model-View: QAbstractItemModel (и потомки), QAbstractItemView (и потомки) ну и "контроллер", то есть делегат.

И вот допустим мы отображаем некий список (произведя его из QListItemModel) в некоем вью (произведя его из QListView). Стандартные средства - хороши, пока их хватает. Иконка, подпись, чекбокс, все есть. Раскраска - стайлшитом.

Идем дальше, стандартных средств не хватает, хотим нарисовать полоску/иконку/хреновинку. Ну отлично, QStyledItemDelegate, базовый класс нарисует основу, мы потом разукрасим.

Правда выясняется, что оформление...

AVX2 и VPGATHERDD - продолжение

Продолжаем дневник программиста на AVX2 (начало и продолжение).

Добрался до 4-го места, которое хотелось пооптимизировать окончательно уже года два как: берем 16-битные целые (RAW-данные), конвертируем в плавучку, вычитаем черный, результат записываем. То есть первый этап дебайеризации.

Параллельно считаем RAW-гистограмму и карту пересвета-недосвета (на самом деле там карта экспозиции считается, а не просто пересвет-недосвет, а дальше она визуализируется с лимитами, все что выше/ниже лимита раскрашивается.).

Вот в этом месте VPGATHERDD (из RAW-значений в экспозицию по LUT) внезапно дал выигрыш...

Еще про AVX2 и VPGATHERDD

Продолжение вот к этому вот тексту и к тамошним комментариям:

1. Собрался с духом и переписал тройку мест на 256-битные команды. Помогло: время исполнения этих кусочков упало на 15-25%. Буду дальше писать.

Это без особой оптимизации, старый код у меня SSE3, никаких BLENDPS/EXTRACTPS не использовалось, соответственно и AVX2 - это чисто замена _mm_ на _mm256_ ну и типы 256-битные. В уже переписанных кусках буду еще смотреть на DPPS: на SandyBridge эта инструкция выигрыша не давала, но может быть поможет на Haswell+.

2. А вот с VPGATHERDD - сплошное разочарование:

  • Для гистограммы (когда gather, потом инкремент, потом поэлементная запись) - получается серьезный проигрыш в производительности, а код сложнее.
  • Для операций вида bitmap[index][channel] = contrast_curve[value] проигрыш тоже есть, хотя и незначительный. Совсем оптимизированное (читаем только 6 элементов, для альфа-канала берем defaults т.е. через masked load) - совсем незначительно медленнее, единицы процентов на всю функцию, но медленнее.

Уж не знаю, кому эта VPGATHERDD в таком виде нужна. Ну разве только на новых процессорах она побыстрее.

Про AVX2

Давненько я в этом блоге на ассемблере не писал.

Вот значит кусочек FRV, который накладывает выходную тоновую кривую. Точнее, два кусочка, один на старом добром SSE2 (которого там ровно одна команда, сконвертировать float-int), а второй - на новом модном AVX2, правда 128-битном, но зато с table lookup.

#ifndef USE_AVX
        uint32_t __declspec(align(16)) dpix[4
...

Q: Qt, Dynamic OpenGL, OES/ARB extensions

Вот что-то наткнулся и смотрю как на новые ворота.

Преамбула:

  1. Вот есть такой Qt, в нем есть работа с OpenGL
  2. У кого OpenGL нету или кривой - есть библиотека ANGLE, которая эмулирует OpenGL ES2 (или 3) поверх DirectX 9 (или, соответственно, 11).
  3. OpenGL ES от простого отличается, в числе прочего, названиями extensions. Ну, к примеру, GL_OES_get_program_binary у ES/GL_ARB_get_program_binary у обычного.
  4. У Qt 5.4 (под Windows) появилась возможность динамической загрузки имплементации OpenGL. До инициализации QApplication говоришь что хочешь, а дальше
  5. ...

Трудовые будни

Жалуется юзер, странной жалобой: 64-битный FRV падает, 32-битный - работает. Система, естественно, 64 бита.

Через три дампа (научили его снимать через Task Manager) и три версии софта проблема выяснилась:

  • FRV для отрисовки дерева фолдеров использует Qt-шный компонент (QDirModel)
  • Тот, в свою очередь, за иконками ходит в систему, все кончается в SHGetFileInfo()
  • В системе, как мы знаем можно зарегистрировать своего провайдера иконок и рисовать красивые иконки (так делает, к примеру Dropbox: для синхронизированных каталогов-файлов одна иконка, для тех что в процессе - вторая).
  • Ну и у юзера оно так и есть, там DBROverlayIconBackuped.dll, который часть Делловского (ноутбучного?) бэкапа.
  • Ну и 32-битная версия этого добра - дает угля иконок, а 64-битное к ней обращение (уж не знаю битность самого DLL, может где-то по дороге транслируется) - все рушит. Собственно и дампы кончаются в этом DLL, но я только со второго дампа начал подозревать чужую ошибку, а не свою.

Это, граждане, ужас. Везде БЕЗДНЫ.

Из говна и палок

На поведение Windows при вставлении-вынимании флешки я уже жаловался: событие не прилетает, нужно поллить. Потом жаловался и на OS X - событие прилетает, но до того, как устройство появляется в списке томов. Тоже поллинг.

Но действительность на OS X превосходит ожидания.

Если мы размонтируем устройство сами, через FSUnmountVolumeSync(), то поллинг работает нормально: прилетает callback, дальше по таймеру несколько раз читаем список томов, из списка размонтированный том пропадает, все отлично.

А вот если размонтировать через Finder, то жизнь ГОРАЗДО...

WM_DEVICECHANGE на OS X

Продолжение к WM_DEVICECHANGE и все все все (потому и заголовок такой), только на маке.

На OS X, казалось бы, все хорошо, там есть такое:

DARegisterDiskAppearedCallback(m_session, kDADiskDescriptionMatchVolumeMountable, mountCallback2, this);

Ну и дальше в том же духе. И на всовывание USB-карточки прилетает callback.

Дальше мы хотим узнать, что же нам всунули, идем получать список маунтов:

CFURLEnumeratorRef enumerator = CFURLEnumeratorCreateForMountedVolumes(...

Про QFileSystemModel

А вот возьмем, к примеру, Qt и решим вывести дерево фолдеров (папок, каталогов).

С незапамятных времен в Qt есть QDirModel, которая тянет данные синхронно и, поговаривают, очень от этого тормозит. Не заметил, чтобы очень, но на долю секунды при открытии большого каталога по сети - ну да, есть. Самое плохое в этом то, что оно блокирует UI пока читает каталоги, а пересадить в отдельный (от View) thread, судя по всему, не получится.

А есть новая прекрасная QFileSystemModel,...

WM_DEVICECHANGE и все все все

Обложился USB-кардридерами, сую в них карточки и высовываю и чувствую, что схожу с ума.

Вот есть сообщение WM_DEVICECHANGE, оно прилетает

  1. когда я вставляю USB-флешку (не карту)
  2. когда я подключаю ридер (без карты)
  3. когда я подключаю ридер с заранее вставленной карточкой.

А вот если подключить ридер без карты (прилетит сообщение), а потом вставить карточку - на вставление карточки WM_DEVICECHANGE не прилетает.

Kaspersky Antivirus со мной солидарен, свое "обнаружен съемный диск" он показывает в случаях 1 и 3 (ну а...

Про компьютеры

Есть вот такое мнение, что "компьютеры перестали становиться быстрее". Пару лет назад я его даже развеивал на хайлоаде, но в докладе упирал на SSE/AVX/итп.

Но тут понадобилось попрофайлить кой-чего на Core2 (у котогого aligned/unaligned access резко отличаются). Достал с полки старый свой макбук, 2007-го года, Core2 Duo, ~2.2гигагерца (могу ошибаться, по памяти пишу). Надо теперь собрать Qt. Вот Qt 5.3.2 собиралося у меня почти 7 часов (400 с чем-то минут по time), на двух ядрах.

Ну ладно, думаю, у этого ноутбука была тяжелая судьба, я ему всю систему охлаждения перебирал т.к. он throttle-лся (термопаста повысохла), может опять болеет.

Отобрал у жены ноут. Celeron T3100, то же поколение Сore2, 1.9гигагерца, винды. Вот 2010-я студия собирает, 5 часов уже прошло, до QtDeclarative добрались. Значит еще не меньше часа.

Для сравнения, i7-4770 собирает тот же Qt 5.3, судя по датам создания файлов, 36 минут. В 10 раз быстрее. Да, вдвое больше ядер, ~вдвое больше частота, но еще 2.5 раза просто от большей лучшести.

Это вот я к тому, что те кто гордо не апгрейдит свои Q6600, они на самом деле заметно отстали от.

Загадка DPI

Вот значит вроде порешал проблему:
  • Все шрифты теперь в pt, а не в px
  • Практически все иконки - в SVG (осталась, буквально, одна, но отчего-то в Qt stylesheets не работает svg, хотя по доке - должна, ну соберусь с силами и буду генерировать ее на скаку)
  • Размеры окон, там где надо (автомат работает так, что мне не нравится) - в em
  • чего-то еще вылезло, но вот не могу уже вспомнить
И все на винде заработало прилично. Несу на мак. Собираю. Ой.

И вот гложет меня теперь вопрос:

Отчего на одинаковом мониторе (виртуальном, 1920x1200, никакого HiDPI, никаких специальных настроек, операционки поставлены по дефолту) 9pt шрифт на винде (приблизительно) соответствует по размеру 14pt на маке?. Один и тот же шрифт. Тахома.

Про HiDPI на винде

Поступили жалобы, дескать FRV на Win8(.1?) на HiDPI-мониторе выглядит криво.

Поставил (на макбук с ретиной, это не 4k-ноут на который жаловались, но достаточно близко), буду разбираться.

Но!

Выглядит криво там ПОЧТИ ВСЕ. Вот начиная с инсталлятора этой самой 8.1: что выбор раздела диска на который ставить, что ввод серийника, что вообще вся инсталляция до перезагрузки - все нужно рассматривать мелкоскопом.

Ну и дальше аналогично. Если программы самой MS еще нормально (хотя вот MS IE мелковат, на мой вкус), то практически все 3rd party - просто катастрофа местами.

То есть размеры диалогов то очень много где заданы жестко, шрифты - масштабируются, в результате все разваливается вообще нахрен. Или, наоборот, там где размер шрифта жестко задан - все выглядит в пропорцию, только ОЧЕНЬ МЕЛКОЕ.

Похоже что вот Apple, с его Logical Pixels/Physical Pixels (и первые - или 1x1 или 2x2 вторые) - поступил вот верно. Уж как минимум, старые, не Retina-aware, программы вели себя прилично. Ну и в подавляющем количестве мест (кроме битмепов и OpenGL) оно скейлилось как-то само, внутри.

А вот виндовая гибкость (возможность поставить произвольный масштаб) - разработчиков будет больно кусать. Оно и раньше было не подарок, но обычное увеличение было процентов 120, а на HiDPI экранах оно ближе к 200.

Ну и да, разнообразие убъет всех: 4k может быть и 15" и 32", понятно что "увеличение" на них сильно отличается. Как сохранить в такой ситуации UI (если временами его по пикселям подбираешь) - вот не знаю, да.

Q: windows file associations

Вот есть такой foobar2000. Там в настройках есть раздел Shell Integration, если его открыть, там есть линк 'Manage file type associations', который открывает Control Panel, уже открытую в нужном месте, в ассоциациях foobar2000:

Хочу такого же.

Дошел до:

control.exe /name Microsoft.DefaultPrograms /page PageDefaultProgram
Оно открывает почти нужное: там список всех программ, до нужного мне...

Pages

Subscribe to Программирование