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

Полна чудес могучая природа

А в SSE4.1 оказывается есть минимум-максимум для 16-битных целых. 8 штук зараз.

Хреначит 11 гигабайт в секунду, сдается мне что параллелить по ядрам дальше смысла нет, упрешься в память.

И dot-product есть, правда только для float/double.

Чешутся руки забить на владельцев AMD и всего младше Penryn, держите меня...

Убийца предсказателей переходов

      if (cr2_slice[0]) {
        jidx = jrow*jwide + jcol;
        i = jidx / (cr2_slice[1]*jh.high);
        if ((j = i >= cr2_slice[0]))
                 i  = cr2_slice[0];
        jidx -= i * (cr2_slice[1]*jh.high);
        row = jidx / cr2_slice[1+j];
        col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
      }
Для понимания контекста:
  • Этот кусок зовется на каждый пиксел и рассчитывает, куда именно поместить распакованный из CR2 пиксель (там не так просто все).
  • jidx - номер пикселя в потоке, плавно возрастает.
  • Изображение поделено на cr2_slice[0] полос шириной cr2_slice[1] и одну полосу шириной cr2_slice[2].
  • cr2_slice[0] - небольшое число, 1-3-5
  • j - соответственно - 0 или 1.

На 15 мегапикселях - 330 миллисекунд. Разворот if правильный (чтобы было не 1+j, а честно 1 или 2) - минус 70 миллисекунд. Замена на таблицу с заранее насчитанными оффсетами - минус 200 миллисекунд. Но все равно много, перемудрили в кэноне. Главное, их "слайсы" вполне можно было бы распаковывать впараллель (как они жмутся параллельными Digic-ами), если бы в RAW были бы смещения начал. Ан нет.

Rawspeed: записки на манжетах

Есть такая библиотека RawSpeed, которая натурально написана с душой и склонностью к правильным оптимизациям. Например, файлы .CR2 распаковываются раз в пять быстрее чем это делает LibRaw.

В стремлении эту несуразность поправить, фтыкаю в ее исходники одним глазом, вторым и третьим - в результаты прогона профайлера на LibRaw и RawSpeed на одном и том же файле.

И вижу интересное (в исходниках, не в профайле): Canon 1D Mark III обрабатывается у Коффина в dcraw (и у нас) специфическим способом. Там, как обычно, грубый хак, но работающий. Касается этот хак буквально двух пикселов по ширине на рамке, видимой части изображения - не касается. Ага, сказали мужики и достали лом побольше пошаговый отладчик и grep.

Зная, что меня читают некоторые пользователи RawSpeed, имею сказать, исключительно в информационных целях:

  • RawSpeed извлекает уровень черного только из DNG и NEF, в остальных случаях берется predefined-значение из базы данных по камерам.
  • Уровень черного - это одно число. Даже не два, как в LibRaw/dcraw и не сложная структура, как оно бывает в некоторых камерах вроде PhaseOne (да и DNG - тоже. DNG-шные теги усредняются).
В результате будет два интересных эффекта:

Обилие демозаик

Тем временем, вышла LibRaw 0.12 (beta).

Усилиями контрибьюторов (как их писать на нашем, "вкладчики"?) была добавлена большая пачка разнообразных методов демозаики.

К несчастью, лицензионные ограничения не позволяют распространять все это богатство на тех же условиях, что и LibRaw (LGPL/CDDL), поэтому часть этих методов раздается отдельно, под соответствующими лицензиями:

  • Демозаика DCB и шумопонижение FBDD (автор: Jacek Gozdz) добавлена в основную LibRaw, ибо лицензия позволяет.
  • LibRaw-demosaic-pack-GPL2 включает в себя:
    • Алгоритмы, реализованные в Modified DCRAW by Paul Lee: VCD, modified AHD, AHD+VCD и модифицированные медианные фильтры.
    • Алгоритмы из Perfect Raw by Manuel Llorens (удивительно, но не нашел куда нормально дать ссылку): AFD и LMMSE
  • LibRaw-demosaic-pack-GPL3: AMaZE из RawTherapee 3 и подавление хроматических аберраций оттуда же.

Удивительное дело, но на тех снимках, на которых я тестировался (попались детские портреты) разница между алгоритмами - минимальна. Да, она есть, она видна на мелких деталях (а где же еще), но стоит ли овчинка того или нет - мне сложно сказать.

Beware: git(hub)+git+subversion= many epic fails...

Вынужден с огорчением признать, что такая вот схема:

GitHub  локальный git  SVN-репозиторий
оказалась нежизнеспособной, хотя изначально не казалась таковой.

У меня это, правда, осложнялось тем, что в SVN-е запомнена долгая и трудная жизнь, а на GitHub я поэкспортил только /trunk/, только одного проекта, да и то не весь, а только начиная с публичных версий.

C++ streams compatibility...

Граждане программисты,

Я - человек темный, граблями причесываюсь на фортране-77 все еще программирую. Но мне пишут, что дескать в современных C++-стримах все сделано по уму в смысле буферизации и работают они временами сильно быстрее, чем любимый мой FILE*

Собственно, сомневаться причин нет, в тестах так оно и получилось (и разница заметная), но мучает меня вопрос с совместимостью.

Мою LibRaw на чем только не собирают, вот даже на Maemo, а давеча я проблемы с Visual Studio 2003 правил.

Отсюда вопросы (сам я за всем этим не слежу, проще спросить):

  • Интерфейс то стримовый за последние лет 7-10 - он вообще как, стабилизировался?
  • Следует ли ожидать всяких открытий чудных, вроде того что метод есть, но не работает?
  • С Linux/Mac проблем нет, я вижу что в gcc 4.x все (на первый взгляд) нормально. А что с виндами, причем как в ипостаси Visual Studio, так и cygwin/MinGW? Может есть какая-то табличка по совместимости хотя бы по Visual C++

Про Amazon EC2

Развлекаюсь тут с Amazon EC2 и вот чего не могу понять

Хочется, на самом деле, SUSE 11.2, потому что весь девелопмент проекта на нем и бинарники, соответственно, переносимы без лишних ужимок (и почти гарантированно думать про это не надо)

Но! Я попробовал два готовых имаджа с SUSE нужной версии и нужной битности и оба не загрузились. На консоли неясное, по ssh не пускают. Попал на круглую сумму, центов на пять.

С Амазоновским AMI (Amazon Linux) - никаких проблем, но см. выше.

Риторический вопрос, это опять моральные индусы меня окружают или же просто два раза из двух не повезло?

Update: сошлись с ними на 12-й федоре. И проект собирается (gcc 4.4 из коробки и все такое) и имеющийся образ с EBS - загрузился.

LibRaw 0.10 и 0.11

Некоторые пользователи LibRaw тусуются здесь, поэтому я тут и поспамлю немножко.

LibRaw 0.10 Release
Это формальный выпуск, признание того факта, что версия 0.10 - стабильна, каких-то значимых нареканий на нее за лето не было. Значимых отличий от 0.10-Beta3 нет.
LibRaw 0.11 Beta1
А это, наоборот, дивный новый мир с дополнениями и изменениями:
  • Выходное изображение (результат) можно кропать. Кроппинг делается до постпроцессинга, поэтому для маленького выходного размера постпроцессинг будет очень быстрым*.
  • Сильно изменена обработка вычитания уровня черного: теперь для всех камер (за единственным, но никому не интересным исключением, которое я просто протестировать не могу**) на этапе распаковки RAW-данных вычитание черного не производится. Дальше можно вычитать одним из трех способов: постпроцессинг (dcraw_process()) сделает все сам, если вы делаете демозаику и т.п. сами - вам подойдет новый вызов LibRaw::subtract_black(), ну и полностью самостоятельно все можно делать, данные черной рамки доступны и все такое.
  • Ну и всякие изменения по мелочи, скажем аллоцированное dcraw_make_mem_image()(_mem_thumb()) теперь надо освобождать через dcraw_clear_mem(), обсуждению этого парадокса посвящен предыдущий пост.

Ну кто так строит.....

С лета у меня висела плавающая бага, все руки не доходили.

Суть в том, что в LibRaw внутри аллоцируется кусок памяти, отдается вызвавшему приложению, а оно, когда с ним наиграется, должно освободить его путем банального free()

И что бы вы думали, в некоторых ситуациях берет и падает в этом самом месте. Не у всех, у меня от одного только пользователя был багрепорт, который впрочем воспроизводился и у меня.

Беда, коль сапоги начнет печи...

Вот, казалось бы, хорошая идея - давить пиковые выбросы прямо в RAW-данных. Hot pixels так можно задавить. Вот мне для LibRaw такой патч и прислали, причем, как я понимаю, он уже вовсю работает в одном опенсорсном RAW-процессоре.

На картике слева (кликабельна, по клику увидите как оно на экране при 150%) показан результат применения этого веселого подхода к снимку resolution target. Сверху - результат фильтрации, снизу - без фильтрации. Холст, масло, Canon 500D, снимок взят с imaging-resource.

И результат совпадает с ожиданиями, если на исходно ч-б картинке обработать каналы независимо, до интерполяции, а потом интерполировать, то появления цветных каемок сложно будет избежать.

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

Такое впечатление, что тестировать результаты собственного программирования - просто не принято в последние годы. Я эту красивую картинку получил в первом же (!) тесте (то, что туда попалась resolution target - случайность, но артефакты полезут на любых контрастных границах).

Похоже, что я излишне суров к Adobe, дивный новый мир опенсорца - гораздо хуже.

P.S. Второй содержательный патч из того же источника - не тестировал пока, хотя он мне идеологически тоже не нравится. Он давит maze artefacts, но должен и малоконтрастные детали тоже сгрызать.

Надевелопили? Придется раздевелопить обратно!

Получил тут от одного индуса (не морального, а настоящего) 40-килобайтный патч к LibRaw, заменяющий мой руками-с-любовью написанный 4-килобайтный Makefile на всякий libtool, Makefile.am и прочие страшные слова (40 килобайт там по той причине, что еще раз, для надежности, включен текст LGPL).

Прикол в том, что никакого реального value не привнесено. Пищалки, перделки, configure, libtool, сверкает и переливается, но профита никакого (результаты работы тестовой фазы configure никак не используются и что будет, если, к примеру, strings.h не найден - неизвестно). А, нет, можно сделать ./configure --prefix=/tmp, но это и все.

Зато многое потерялось, вроде сборки с OpenMP. Еще добавилось много лишних сущностей, всякие враппер-скрипты от того же libtool, лишняя библиотека, библиотеки стали shared (а этого для текущей LibRaw категорически нельзя делать) и т.п.

Зато ВВП увеличен, автор потратил время на производство этого гуана, а я - на его обнюхивание.

Объясняю вышенаписанное автору патча, а он обижается. Вспоминается история с Apache2, когда туда IBM (? не помню точно) принес три мешка Software Engineering, отчего проект не мог выйти из беты лет пять.....

AMD/ATI и GPGPU

Я как-то не уследил, потому что AMD/ATI-шными видеокартами начал интересоваться с выходом HD5xxx, а оказывается все очень весело. На gpgpu.ru это уже пообсуждали, ну я сюда наброшу, в более концентрированном виде.

Раньше высокоуровневым средством для разработки считалок на видеокартах у ATI был Brook+. Однако начиная с какой-то беты ATI Stream SDK 2.0 Brook из SDK исчез.

Читаем в ATI-шном форуме (это август-2009):

Yes, this SDK 2.0 beta is for CPU only. It focuses on OpenCL 1.0 for CPU. Brook+ is now available on SourceForge: http://sourceforge.net/projects/brookplus

Ну ладно, Stream SDK Beta-1 вообще не поддерживает никаких видеокарт, смешно.

Миграция Movable Type -> Drupal. Синхронизация с ЖЖ, наведение марафета, финал

Руководство по прыжкам с парашютом, издание второе, исправленное

Теги/рубрики/категории

При миграции контента с тегами и категориями был предложен такой метод

  1. Делаем категории тегами (чтобы не заполнять значения).
  2. Импортируем.
  3. Меняем тип таксономии категории на "Multiple select/Mandatory".
  4. Правим пути к категориям.

Увы, но где-то на этом пути теряются категории у изрядной части записей и теги - у единиц, повторный импорт лечит только частично. Я подозреваю, что крышу рвет, если есть теги, совпадающие с категориями, но не уточнял.Теги портит LJ Sync, пришлось его еще шашкой....

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

С шашкой на Drupal: LiveJournal Sync Ugly Hack

Синхронизация Drupal с ЖЖ оказалась гораздо более простым делом, чем в случае Movable Type:

Ну, если быть точным, то для LJ Sync нужно поставить еще патч из его pending patches, а то синхронизированное туда приезжает тут же обратно, второй копией.

А если быть совсем точным, то LJ Sync не работает с PostgreSQL. REPLACE INTO {table}, убил бы нафиг....

Но. LJSync делает куда больше чем не нужно:

  • Вытаскивает из ЖЖ записи, которые там появились независимо. Это хорошо, если есть адын standalone-блог и адын ЖЖ, но у меня два стандалона гадят в один ЖЖ.
  • Темизирует look-and-feel Друпала "под ЖЖ". С синенькими заголовками комментариев и заголовками записей в ЖЖ-шном духе.
  • Для всех ЖЖ-шных комментаторов заводится аккаунт на Друпале. Оно так и на MT у меня было, но на MT эти аккаунты были бесправные, а тут в них можно авторизоваться (если OpenID включить) ну и типа писать.
Всего этого я ну никак простить не мог.

Миграция MovableType -> Drupal. День 2: миграция контента и URL

Предуведомление

Описанная ниже методика предназначена для заливки пустого сайта на Drupal. Задача доливки контента на сайт, где уже что-то есть - не ставилась. Более того, на стадии импорта комментариев все старые комментарии точно будут стерты.

Если вам нужно пополнение имеющегося сайта, то описанные ниже скрипты нужно взять за основу и допилить.

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

Импорт записей

Задача: вытащить записи (посты) из БД MovableType и запихать их в БД Drupal в виде объектов типа Story. Создание Drupal-объекта связано с заполнением нескольких таблиц (node, node_revisions и прочие node_*, url_aliases), пополнением таблицы тегов, другими словами эту работу не хочется делать вручную (SQL-запросами), а хочется перевесить на внутреннюю механику Drupal (ведь при создании записи оно как-то само все делается...).

План работ тривиален и прост:

  • Ставим модули Table Wizard и Migrate.
  • Добавляем нужные поля в структуру данных записи Story (не вручную, включением готовых модулей).
  • Запускаем скрипт, который перенесет нам данные постов в БД Drupal.
  • Импортируем образованную таблицу с постами в Table Wizard.
  • Делаем импорт через Migrate.
  • Полируем результат.
Первый пункт особых вопросов вызвать не должен, обычные модули. За собой потянут Views и Schema, их тоже надо выкачать и поставить, до кучи полезен и Views UI.

Drupal: pathauto и транслитерация

В качестве короткой заметки на тему вчерашнего и ряда следующих текстов.

Для Drupal есть модуль Pathauto, который делает человеко понятные урлы: заменяет пробелы на минусы (или подчеркивания), меняет ужасные /taxonomy/term/NNN на /tags/имя-тега и так далее.

Все из себя настраиваемое и вообще хорошее, если бы не одно но:

  • Оно умеет транслитерацию (в частности, URL данного текста странслировался бы в ...i_transliteratsiya.....
  • Оно умеет формировать URL-ы из кучи макросов (дата, рубрика и все такое), этого богатства более чем хватает для жизни.
  • Но! Включение транслитерации - глобальное. Или мы транслитерируем все (URL заметок, теги и т.п.) или не транслитерируем ничего.
А у меня в блоге принято, что теги русские, а URL заметок - латинские.

Короче, патч: pathauto-transliterate.diff.gz

Если в паттерн для формирования URL включить текст 'no-transliterate-me', то данный текст будет удален, а то что осталось - не будет транслитерировано.

Все очень на скорую руку, только для таксономии (тегов), но там по образу и подобию несложно доточить для других типов - муторно, но можно.

К сожалению, модуль написан достаточно плотно, транслитерация делается на очень ранней стадии, поэтому сделать более удобные макросы по месту [notr-macro] и [macro] - сходу не получилось.

Автор слышал о проблеме и справедливо замечает, что и размножение макросов и отдельные настройки для каждого типа данных - плохо. И я с ним согласен, но вот мне - надо,

При случае, подумаю про эту тему еще.

Миграция MovableType -> Drupal. День 1: постановка задачи

Предуведомление

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

Короче, не нравится - не читайте :)

Статус этих записок

Записки пишутся по горячему, с небольшой задержкой относительно реальных действий. На момент написания первой части (которую вы сейчас читаете) есть ощущение, что все получится, но реальный перенос данных даже на тестовой машине сделан частично. Но уже есть ощущение успеха, минимально необходимая функциональность точно будет, а дальше будем посмотреть.

Зачем переезжать

Моя причина очень простая: мне надоело поддерживать две платформы (Drupal и Movable Type). При этом, по комплексу свойств Друпал побеждает, а значит с MT пора прощаться. А новогодние каникулы - хороший повод позаниматься чем-то полезным.

О несовершенстве мира

Второй день собираю Qt 4.6-RC при помощи VS2008, с каким-то очень переменным успехом:

Если собирать Qt SDK, то ломается при сборке вебкита, moc генерирует файл нулевого размера. Ошибка висит в Qt-шном багтрекере со статусом "не удалось воспроизвести", гугление показало что она бывала и на Qt 4.5.2, хотя у меня 4.5.2 собирался без проблем.

Кроме того, не срабатывали такие вот строчки:

#if QT_VERSION >= 0x040400
    void unsupportedContent(QNetworkReply *reply);
    void downloadRequested(const QNetworkRequest &request);
#endif
хотя версия у меня самая что ни есть 0x040600

При сборке варианта без Qtcreator наблюдался целый ворох странных проблем, тот же moc.exe создавался без прав на исполнение. По десятому разу вроде полегчало и конкретный WebKit вроде собрался без ручных пинков (с пинками, т.е. подменяя файл длины на нормальный - получалось и в первом случае, но неаккуратненько).

Одновременно узнал про jom, на 4-ядерном процессоре ошибки компиляции возникают вчетверо быстрее, ура!

Я вот как подумаю, сколько сил стоит поддержка Qt на всем чудовищном мировом зоопарке, так мне сразу хочется год эдак в 85-й.

Bye-Bye, Movable Type

No-MT.png Как нам пишут в комментариях, а потом мы и сами читаем:

Q: On http://www.movabletype.jp/documentation/mt5/db/mysql-from-sqlite.html I read: From the Movable Type 5, SQLite and PostgreSQL are no longer supported.
A: Yes, it's true. MT5 will deprecate core support for SQLite and PostgreSQL. But, these databases can still be used with MT if a plugin is written to add support; the Enterprise Pack defines the drivers necessary to use the Oracle database with MT.

Вот и выяснилось, чем придется заниматься на новогодних каникулах, писать тестировать LJ-кросспост для Друпала (оказалось, он уже есть, что же я торможу?)

Если кто-то общается с командой MT, передайте им при случае, чтобы думали верхней жопой передней головой, платформа их была выбрана мной исключительно за поддержку PgSQL и только это ее и берегло.

PostgreSQL 8.4.0 UTF conversion

Представим себе типичную ситуацию: есть таблица в UTF8, какой-то клиент вводит туда данные, работая, скажем, в кодировке windows-1251 и вводит, например, знак номера.

Потом другой клиент, работая уже в KOI8-R сделает по этой таблице SELECT и вместо результатов выборки увидит

ERROR: character такой-то of encoding "UTF8" has no equivalent in "KOI8R"

До версии PostgreSQL 8.1.4 выдавалось предупреждение, а три года назад это стало ошибкой, что сделало жизнь невыносимой: во многих случаях спец-символы не важны (скажем, при отладке в консоли), а работающих запросов хочется.

Начиная с 8.1.4 я делаю патчи для этой функциональности: вместо выдачи ошибки и прекращения запроса невыводимый символ просто меняется на пробел. Дошла очередь и до 8.4.0:

Патчи для старых версий тоже можно брать у меня:

Стандартный дисклеймер: если вы не знаете что такое "патч", то он вам не нужен.

P.S. Своего мнения про 8.4 пока не имею, сформирую - напишу. Пока тестирую, в бой выставлять рановато. pg_migrator не понравился, слишком уж много дополнительных условий, в которых я не уверен.

Pages

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