В очень не плохом фильме "Место встречи изменить нельзя" (али, кому ближе, в книге "Эра милосердия"), мудрый Жеглов, объясняет молодому Шарапову, что ему надо "освоить работу со свидетелями". Это же надо осваивать всякого рода менеджерам и прочим новомодным управленцам, коии поставлены вдохновлять и оживлять всевозможных программистов на создание мега программ.
Итак у Вайнеров, разговор Шарапова и Жеглова выглядит следующим образом:
– Вот это и есть третье правило: как можно скорее найди в разговоре тему, которая ему близка и интересна.
– Ничего себе задачка – найти интересную тему для незнакомого человека!
– А для этого и существует четвертое правило: с первого мига проявляй к человеку искренний интерес – понимаешь, не показывай ему интерес, а старайся изо всех сил проникнуть в него, понять его, узнать, чем живет, что собой представляет; и тут, конечно, надо напрячься до предела. Но, коли сможешь, он тебе все расскажет...
Понятно, что у нас тут не СССР и не милиция, а капитализЪм и менеджеры, поэтому окучивать, каждого на предмет интереса никому не надо. И отсюда желание бить по площадям, посредством корпоративов и прочих новомодных выдумок.
Причем не делать этих самых идиотских вечеринок на сотню персон никак нельзя. У всех жеж уважающих себя контор оно есть, так что отсутствие не поймут-с.
пятница, 26 декабря 2008 г.
Про корпоративы
четверг, 18 декабря 2008 г.
Про оптимизацию компилятором
Пытаюсь написать несколько функций для работы с картинками. Понятно дело пытаюсь, оптимизировать, собственно к этому два замечания.
Сравнение оптимизации компиляторами MSVS 2003 и MSVS 2005
Один и тот же код (функция масштабирования ) компилирую на MSVS 2003 и MSVS 2005 (на 2008 не пробовал). Получаем вот такие графики скоростей (под скоростью здесь понимается размер результирующей картинки поделенный на время работы функции):

Что за всплески в точках меньших 1.0 - не знаю, пока не разбирался. В 1.0 и выше, критичная часть кода уже на ассемблере и компилятор роли не играет. Но очевидно, что народ в Микрософт не сидит сиднем и компиляторы оптимизируют код все лучше (хотя ручной настройкой можно добится существенных результатов)
Директива __forceinline
Директива __forceinline прекрасная вещь. Написал код все того же масштабирования померил время - получается отлично (я для сравнения использовал такие же функции из интеловской либы IPP - моя получилось в полтора раза быстрее, что меня вполне устраивало). Решил немного пооптимизировать код, в том числе одну из внутренних функций наградил директивой __forceinline, которая там смотрелась вполне к месту. Замерил время. Увеличилось в полтора, два раза. Так что дурное использование __forceinline может дать результаты обратные тем, которые предполагались.
воскресенье, 14 декабря 2008 г.
Про оптимизацию функции memset используя SSE
Продолжаю интересоваться возможностями SIMD команд в плане оптимизации своего кода. Сегодня поговорим, про заполнение памяти и соответственно функцию memset.
Функция memset, как известно, заполняет область памяти переданным байтом, соответственно на вход получает указатель на эту самую область и сам байт. Поскольку задача оптимизировать функцию с использованием SSE команд, писать мы будем на ассемблере. А значит, параметры функции будем передавать в регистрах процессора. Договоримся следующим образом. Указатель на память, которую необходимо заполнить передаем в регистре EDI, размер памяти (в байтах) – в ECX, а значение которым будем заполнять - в EAX.
Чтобы работать с ассемблером непосредственно в Visual C++ рекомендую, кроме служебного слова _asm, посмотреть в MSDN, что означает вот такая конструкция __declspec(naked). Местами это сильно облегчит жизнь.
Стандартный вариант функции memset выглядит следующим образом
mov bl,al
mov bh,bl
mov eax,ebx
shl eax,10h
mov ax,bx
mov ebx, ecx
shr ecx, 2
rep stosd
mov ecx,ebx
and ecx,3
rep stosb
Наша задача ускорить его, используя SSE команды.
Но прежде чем предложить измененный вариант, необходимо поговорить о том, как мы будем осуществлять сравнение скоростей. Я набросал простенькое консольное приложение, которое выделяло память, вызывало 1000 раз функцию и замеряло время. Размеры блоков варьировались от 50 байт до 10 мегабайт.
Когда мы используем SSE, следует учитывать, что память, с которой мы работаем, должна быть выровнена к 16 байтам (иначе пересылка содержимого регистров XMM в память будет крайне медленной). Поэтому работа новой функции разбивается на три этапа. Первый заполняем память командой rep stosb, до того момента пока указатель не будет кратен 16, затем помещаем во все байты регистра XMM0, и в цикле копируем его в память. И, наконец, вновь при помощи rep stosb заполняем остаток. На первом и последнем шаге размер буфера будет от 0 и до 15 байт.
Выглядит эта новая функция, следующим образом:
test ecx, ecx
jz func_exit
cmp ecx, 0x1F
jge sse_part
mov bl,al
mov bh,bl
mov eax,ebx
shl eax,10h
mov ax,bx
mov ebx, ecx
shr ecx, 2
rep stosd
mov ecx,ebx
and ecx,3
rep stosb
jmp func_exit
sse_part:
mov ebx, edi
and ebx, 0x0F
jz xmm_align
xor bl, 0x0F
inc ebx
sub ecx, ebx
loop_byte_2:
mov [edi], al
inc edi
dec ebx
jnz loop_byte_2
xmm_align:
pxor xmm0, xmm0
movd xmm0, eax
punpcklwd xmm0, xmm0
pshufd xmm0, xmm0, 0
movdqa xmm1, xmm0
psllw xmm1, 8
por xmm0, xmm1
mov ebx, ecx
and ebx, 0x0F
shr ecx, 4
loop_xmm:
movntdq [edi], xmm0
add edi, 0x10
dec ecx
jnz loop_xmm
mov ecx, ebx
rep stosb
func_exit:
sfence
emms
ret
Итак, и первый и второй вариант прекрасно работают. Теперь про интересное, а именно посмотрим на график скорости в зависимости от размера заполняемого блока. На нем по вертикальной оси прописаны размеры блока в байтах, гистограммы показывают скорость копирования в МБ/сек.
Не трудно видеть, что обычная функция существенно обгоняет SSE вариант на блоках до 1 мегабайта, однако проигрывает практически вдвое в случае, когда размер блока больше 1 мегабайта. Дополнительные измерения на отрезке от 500 000 байт до 1 000 000 байт показали, что смена лидера происходит в случае, когда размер блока примерно равен 590 000 байт. Не трудно догадаться, с чем связано такое поведение. У процессора, на котором производилось тестирование, L2 Cache – 512 КБ, соответственно, когда мы заполняли один и тот же блок постоянно, вся работа производилась внутри кеша, пока его хватало. На больших же блоках кеша не хватало, и мы имели резкое падение скорости работы обычной функции. Т.е. фактически мы имеем некорректный тестовый стенд.
Ну и что-то вроде вывода из всего этого хозяйства, который я сделал лично для себя. Если размер блока большой (больше мегабайта), то я пользую SSE вариант и не забиваю голову сомненьями. Если меньше, то смотрю по ситуации. Например, если много маленьких блоков разбросанных по памяти, и работать приходится то с одним то с другим, т.е. гарантировать, что все они поместятся в кешь и будут там постоянно находится я не могу, то снова пользую SSE вариант. А если надо 10 байт обнулить и потом с ними постоянно работать, то ну его этот SSE буду пользовать классический rep stosb.
А если серьезно, то вывод таков, что при оптимизации, надо не забывать учитывать наличие кеша процессора, и писать код с оглядкой на этот замечательный механизм. Будет время напишу более подробно, ибо вот memset то мы оптимизировали, а на подходе функция memcpy, которая так же крайне важна и нуждается в оптимизации.
четверг, 11 декабря 2008 г.
Про оптимизацию подробно
Решил собрать в кучу всякие мысли про оптимизацию. И расписать все это более или менее подробно.
Чтобы разговаривать по возможности предметно в качестве модельной рассмотрим такую задачу.
Допустим, нам надо генерировать черно-белую картинку (более точно массив байт, где 0 - соответствует белому цвету, 255 - черному). Размеры картинки будем предполагать от 5000 до 10 000 пикселей по каждой из осей. Генерация будет заключаться в отрисовке заданного набора черных прямоугольников (от 500 до 1000 штук, с размерами от 100 до 200 пикселей по каждой из осей) на белом фоне. Так же ограничимся случаем, когда стороны прямоугольников параллельны осям.
Задачка достаточно простая, и имеет массу решений. Однако, нам интересно рассмотреть подход к выбору из этих решений оптимального.
В работе по оптимизации программы можно выделить три этапа или три класса оптимизации.
1. Архитектурная оптимизация
2. Алгоритмическая оптимизация
3. Оптимизация кода
На самом деле они, естественно, не независимы. Нельзя определиться с архитектурой, не учитывая алгоритмы и глупо выбирать алгоритмы, не задумываясь о том можно ли их реализовать оптимально в данных условиях.
Архитектурная оптимизация
Чаще всего дает максимальное увеличение скорости. Здесь оптимизация зачастую определяется не только конкретной задачей, но и контекстом, в котором эта задача решается (причем контекстом в первую очередь).
Обратимся к нашей модели. Нам надо понять: как будет использоваться сгенерированная картинка? Например, возможно картинка нужна нам для вывода на экран. Экраны размеров 5 000 на 5 000 маловероятны, и это позволяет нам при запросе создать только часть картинки. Даже, если по запросу вместо 25 000 000 = 5 000 * 5 000 пикселей, мы будем генерировать 1 920 * 1 080 = 2 073 600 пикселей (т.е. в 12 раз меньше), это даст существенный прирост в скорости генерации (надо понимать, что в зависимости от выбора алгоритма прирост может быть и не 12 кратный, а при особом упорстве можно добиться даже уменьшения скорости, нет вершин, которые бы не взял человеческий идиотизм).
Еще одну возможность, которую следует рассмотреть на данном этапе это использование для генерации картинки нескольких потоков. Особенно актуально это стало в последнее время с появлением все большего числа многоядерных процессоров. Решать этот вопрос надо в тесной связи с тем, какие алгоритмы мы будем использовать. Еще раз следует уточнить, что разные этапы оптимизации тесно взаимосвязаны.
Вопросов о том, как будет использоваться наше решение, можно задать очень много и чем больше мы зададим их на данном этапе, тем меньше вероятность, что нам в дальнейшем придется переделывать все с нуля.
Дабы не быть голословным рассмотрим еще несколько уточнений, которые могут существенно повлиять на выбор варианта решения.
Генерируется ли картинка разово (т.е. приняли набор прямоугольников, сгенерировали картинку, сбросили ее куда-нибудь на диск и забыли) или это итеративный процесс (запросили одно окно из картинки, потом слегка сдвинули окно - запросили, и т.д.). Если итеративный, могут ли данные меняться между запросами? Если данные могут меняться, то каким образом? Прямоугольники только добавляются или и удаляются тоже.
Ответы на эти вопросы позволяют понять, есть ли смыл кэшировать промежуточные результаты, в какой момент отрисовывать прямоугольник (при его добавлении или на этапе генерации картинки) и т.п.
Таким образом, архитектурная оптимизация - это самый первый и наиболее важный этап, и именно он определяет начальный уровень скорости, который мы сможем (или не сможем) увеличить в дальнейшем. Т.е. надо понимать, что, конечно, и хорошую архитектуру можно загнать плохими алгоритмами и не оптимальным кодом, но точкой отсчета для скорости всегда будет служить выбранное архитектурное решение.
Алгоритмическая оптимизация
Алгоритмическая оптимизация начинается тогда, когда с архитектурой мы уже определились, и очередь дошла до выбора алгоритмов. Если на предыдущем этапе, мы определяли, как решаемая нами задача вписывается в общую структуру программы, то теперь нам надо разобрать более тонкие моменты.
Вновь вернемся к примеру с закраской прямоугольников. Самый простой алгоритм, который можно предложить для ее решения такой: проходим по всем пикселям картинки, для каждого пикселя проверяем, лежит ли он внутри прямоугольника или нет, и соответственно выставляем в нужный байт 0xFF или 0x00. Алгоритм ужасен, поскольку в худшем случае (например, когда все прямоугольники совпадают и вырождены в точку), необходимо будет для каждого пикселя проверить все прямоугольники и не найти пересечения. Второй вариант, заполнить сначала нулями весь выделенный под изображение массив, а затем, перебирая прямоугольники, закрашивать покрываемые ими пиксели. На самом деле тоже не слишком хороший вариант, например, когда прямоугольников много и они равномерно покрывают изображения, начальное обнуление массива становится длительной и лишней операцией.
И в первом и во втором алгоритме легко разбить работу на несколько потоков. В первом случае, просто разделив картинку на куски, и обрабатывая каждую часть в отдельном потоке. Во втором, первоначальное заполнение массива нулями разбивать будет, вряд ли целесообразно, а вот массив прямоугольников вполне возможно обрабатывать в разных потоках. И здесь, вполне вероятно, что первый алгоритм, сможет оказаться быстрее второго, просто за счет того, что исходное зануление массива будет общей частью для всех потоков.
Можно сделать вывод, что на данном этапе оптимизации важно определить, нет ли каких-либо особенностей у исходных данных задачи и, если таковые будут обнаружены, соответствующим образом настроить алгоритмы.
Оптимизация кода
Практически к этому этапу решение задачи уже в некотором виде реализовано, а желательно еще и отлажено. На самом деле, прежде чем браться за оптимизацию кода, совсем не плохо иметь модельный вариант реализации, с которым в дальнейшем можно будет сравнивать результаты на разных входных данные. Дело в том, что если до этого момента вполне реально делать все «красиво», т.е. иметь стройный код и хорошую структуру, то оптимизация кода обычно приводит к ухудшению его читабельности и понимаемости. Поэтому наличие рабочей (пусть и медленной версии) сильно облегчает жизнь.
На этом этапе кроме головы и компилятора, понадобятся еще и специфические инструменты - так называемые «профилировщики». Программ таких не сказать, что много, но их есть. Я пользуюсь CodeAnalyst-ом от AMD, он достаточно простой в работе, вполне устраивает меня по функциональности (хотя и имеет корявый интерфейс), а самое главное бесплатен, в отличие от схожей утилиты от Intel, стоящей что-то около 600 долларов (честно говоря, с Intel-овской утилитой не разбирался вполне допускаю, что там и возможностей побогаче и интерфейс поудобнее).
Можно, конечно, делать все на глазок, но это не оптимально. Профилировщик позволяет быстро выделить куски, с максимальным вкладом в время работы программы, и начинать оптимизацию с них.
Именно на данном этапе некоторые из частей кода, возможно, необходимо будет переписать на ассемблере, а некоторые и оптимизировать, используя SIMD инструкции. Однако, здесь важно не переусердствовать, ибо современные компиляторы с оптимизацией кода справляются вполне успешно, и стоит соблюдать баланс между «читабельностью» (которой код на ассемблере обладает в минимальной степени) и скоростью работы.
На этом пока все. В данном случае отзывы и замечания по статье приветствуются.
среда, 10 декабря 2008 г.
И здесь тоже непонятное
"Этот блог заблокирован в связи с возможным нарушением Условий предоставления услуг Blogger. Вы не сможете публиковать новые сообщения, пока блог не будет пересмотрен и разблокирован.
Если вы не запросите пересмотр, блог будет удален в течение 20 дней."
Так и не понял почему:) Вроде ссылок всего штук пять сбоку висит, так они там все время висят, сообщения все вполне пристойные... вообщем вот такой он искусственный интелект, бум ждать, когда придет обычный и может быть разблокирует, или хотя бы растолкует чего жеж не так. А может надо перебираться куда в другое место....
UPD: Кажись разблокировали - оперативненько. Что радует.
суббота, 6 декабря 2008 г.
"Он и в третий раз ходил за елкой..."(с)
В пятницу эпопея с картинами повторилась, художники вернулись. С нетерпением жду понедельника, узнать удержалась ли живопись на стенах.
UPD: Как и следовало ожидать - не удержалась.
четверг, 4 декабря 2008 г.
Про Opera 10.0 Alpha
Не впечатлила. blogger.com как обычно, т.е. совсем не так как надо. Разве что теперь по Ctrl+Shift не открывается предварительный просмотр (что в 9.6 просто конкретно задалбливало).
Speed dial - долго думал, но сайты так и не подгрузил - что из рук вон.
Смена скина на старый, конечно, сработала, но как-то не совсем, т.е. такое ощущение, что высота закладок стала больше.
Да и в принципе, меня как-то бета-тестинг не возбуждает. Через это снес эту альфу, буду пытаться привыкать к ИЕ7.
Про совпадения
Бывают в жизни совпадения.
Решил попрощаться с Oper-ой. Собственно к ней есть несколько претензий.
1. Далеко не все сайты отображаются нормально. Например, писать в этот блог практически не возможно.
2. Очень долго выгружается. Понятно почему - кешь здоровый и явно организован через известное место.
3. Жрет ресурсы. Когда начал заниматься оптимизацией и измерять время выполнения функций, стало заметно, что от того запущена или нет Opera время зависит весьма существенно.
4. Очень жрет ресурсы, т.е. открыв страницу может подвиснуть на 1-2 секнуды для рендеринга (как я думаю, может и еще для чего)
В остальном очень хорошая, плюс кеширует все подряд, а трафик пока хоть и безлимитный, но не то чтобы совсем халявный.
Вообщем решил вчера вечером, вчера же попробовал Firefox. В принципе, нареканий особых нет, по пп. 1, 2, 4 все вроде в порядке. И даже выглядит не сказать что ужасно. Конечно, не кеширует, но это не приоритетно. Но дернул же меня черт. Очень мне у Opera нравилась "Speed dial" страничка. Решил что надо бы такую заиметь и на Firefox. Нашел какой-то add-on, скачал. Мать моя родная - страничка у них получалась, страшнее чем моя жизнь. Т.е. отрендерить для эскиза страничку в большой размер, а потом замасштабировать идея в целом хорошая, но люди добрые, соотношение сторон то надо сохранить! Т.е. надо хотя бы в целом взглянуть на результат и как-то что-то докрутить. Ну ужас же смертный.
Пытался так же перед сном поставить Chrome. Скачал файлик на полметра, который как я понял после запуска решил докачать что-то крайне необходимое из интернета. Извините, но ну его на фиг. Чай не в америках живем, чтобы с каждой машины инсталляцию заново скачивать. Т.е. может оно можно и как-то найти так что сразу одним файлом скачал и поставил, но искать меня как-то в три часа ночи уже заломало.
Сегодня на работе попробовал пользоваться IE7 - опять же по всем пунктам кроме 3 подходит (третий просто не проверял). Скачал и навесил на него какой-то мега изменятель, который дал возможность выкинуть комбик поиска (ибо если можно искать в адресной строке, то на фига бы он сдалось) и поставить главное меню на его привычное место (почему в IE7 эти опции не вынесены в настройки самой MS понять отказываюсь, честно говоря это похоже на вредительство, ну или на идиотизм, что встречается существенно более часто). Заметил кстати, что порботав с Oper-ой, отучился закрывать броузер, и чуствую себя не уютно, если он не весит в панеле задач.
Но собственно про совпадения.
Вечером зашел на softpedia (единственный кстати более менее приличный сайт из софтархивов, остальные из видинных, либо новодельная помойка в которой за adsense программу уже не разглядеть, либо как доунлоадс.ком - хер чего найдешь и ели ворочается) и чтобы вы думали - Opera 10.0 альфа. Вот скачал - буду поглядеть.
Несколько кусков кода
Хочу предложить некую подборку маленьких кусочков кода, для стандартных задач, часто встречающихся при программировании на MMX-SSE. Тут никаких откровений не будет, но может кому пригодится.
1. занулить все биты в SSE регистре (xmm0)
pxor xmm0, xmm0
2. выставить все биты в SSE регистре (xmm0)
pcmpeqb xmm0, xmm0
3. дублируем word CX в xmm0
movd xmm0, ecx ; xmm0 = ** ** ** ** | ** ** ** ** | ** ** ** ** | 00 00 VV UU
punpcklwd xmm0, xmm0 ; xmm0 = ** ** ** ** | ** ** ** ** | 00 00 00 00 | VV UU VV UU
pshufd xmm0, xmm0, 0 ; xmm0 = VV UU VV UU | VV UU VV UU | VV UU VV UU | VV UU VV UU
4. дублируем байт CL в xmm0
movd xmm0, ecx ; xmm0 = ** ** ** ** | ** ** ** ** | ** ** ** ** | 00 00 00 UU
punpcklwd xmm0, xmm0 ; xmm0 = ** ** ** ** | ** ** ** ** | 00 00 00 00 | 00 UU 00 UU
pshufd xmm0, xmm0, 0 ; xmm0 = 00 UU 00 UU | 00 UU 00 UU | 00 UU 00 UU | 00 UU 00 UU
movdqa xmm1, xmm0 ; xmm1 = 00 UU 00 UU | 00 UU 00 UU | 00 UU 00 UU | 00 UU 00 UU
psllw xmm1, 8 ; xmm1 = UU 00 UU 00 | UU 00 UU 00 | UU 00 UU 00 | UU 00 UU 00
por xmm0, xmm1 ; xmm0 = UU UU UU UU | UU UU UU UU | UU UU UU UU | UU UU UU UU
5. Перевернуть SSE регистр побайтово
__declspec( align(16) ) static BYTE g_carShufleMask[16] =
{
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
};
_asm
{
movdqa xmm1, oword ptr [g_carShufleMask]
pshufb xmm0, xmm1
}
Последнее надо использовать аккуратно, pshufb - SSE2 команда (например, MSVC2003 вообще про нее не знает).
На последок. Крайне рекомендую найти и почитать статью "Using Block Prefetch for Optimized Memory Performance" очень хороший пошаговый разбор оптимизации функции memcpy с использованием кеша процессора. Скорость увеличивается в 2.5 раза (по статье в 3, но у меня на четырех компьютерах было от 2 до 2.5). Понятно, что ускорение memcpy (в особенности в тех условиях, которые заявлены в статье) не слишком интересно - но в целом почитать для начинающих вроде меня полезно.
Про искусство
Как сказал один не глупый дядя: "из всех искусств важнейшим для нас является кино". Т.е. сказал он не много по-другому, но цитата прижилась именно в таком виде.
С кино на работе все складывается прекрасно, можем сконвертить практически из чего угодно во что угодно, и местами даже сделать это хорошо. Поэтому последнее время все больше имеет место быть цирк, причем на роль клоунов иногда подписывают местные кадры, а иногда зазывают со стороны. Сегодня цирковое представление осуществлялось силами заезжей труппы.
Решило наше начальство облагородить новые помещения, поразвесив на стенах всякую живопИсь. Ну живопись не живопись, а распечатанные на большом ватмане картинки (как оно выглядит ежели исходник в jpeg, можно себе представить). Причем доверить такую сложную работу местным творческим личностям не решились, пригласили специалистов со стороны (вопрос стоимости опустим как не имеющий к искусству никакого отношения).
В целом идея эта, не нашла отклика в моем сердце, ибо я предпочитаю помещения с чистыми стенами и с минимумом мебели. И положа руку на сердце с минимумом людей. Ибо, во-первых, по моему глубокому убеждению, производительность труда программиста обратно пропорциональна количеству народу в помещение. А, во-вторых, которое является причиной того, что, во-первых, большинство программистов страдают аутизмом разной степени тяжести (конечно, не в медицинском, а сугубо в бытовом смысле).
Так вот вешать те полотна, пришли сразу трое специалистов. Как по мне, так когда три взрослых мужчины вешают одну картонку формата А2, это мягко говоря не понятно. С другой чего бы я понимал в искусстве.
Поскольку специалисты явно скорее художники, нежели инженеры, они полностью отказались от презренной техники, и вешали картины на глаз, используя из приборов только рулетку и шуруповерт. Т.е. мне казалось, что приспособа типа "уровень" весьма полезна в деле выравнивания прямоугольника относительно горизонтальных поверхностей. Но снова чего бы я понимал в этом самом искусстве.
Вообще повесить то они их повесили. Но поскольку к разработке способа крепления был применен творческий подход, то пока они вешали в одной комнате, в другой оно отваливалось. Учитывая, что сделать нормальный подвес не шибко сложная задача, решенная миллион раз, профессионализм поражает воображение.
Озлобляет на самом деле другое, поскольку одно из мегаполотен вешали непосредственно над моим столом, то последние два часа на работе поработать так и не удалось. В целом это не страшно, понятно, что развешивание полотен существенно важнее той херни, что я пишу. Но когда рабочий день подошел к концу и народ начал потихоньку разбредаться, вешатели озаботились присверливанием какой-то очередной ерундовины в коридоре. Соответственно вопрос, отчего было вначале не оформить этот самый коридор, а уже опосля того, как народ уйдет домой заняться созданием инсталляций по комнатам (раз уж в выходные всю эту ерунду развесить ни как не получалось).
суббота, 15 ноября 2008 г.
Про программы
За последнее время все больше находится бесплатных программ, при этом отличных во всех отношениях, т.е. решающих заявленные разработчиками задачи. Причем многие хороши настолько, что установив, не возникает желания в срочном порядке написать свое для того же самого только лучше и с дополнительным мегафункционалом. Раньше такое бывало крайне редко, а с бесплатными программами практически никогда.
Есть мысль поделиться сокровенным. Так сказать, опубликовать списком и изложить подробно все прелести. Буде появится время - займусь
пятница, 14 ноября 2008 г.
Про непонятное
В новом здании в которое переехала контора, на первом этаже сидит охранник. И это не вызывает удивления, ибо должен же кто-то не давать выносить имущество фирмы. Т.е. если бы он занимался именно этим все было бы понятно. Спускаешься ничего не подозревая с коробкой из под ксерокса, а он тебе: "а документики у Вас на вынос имеются? Нет? Тогда будьте любезны получить таковые." И все понятно.
Или приходишь ты на работу, полный энергии написать нечто неописуемое, что выведит родную контору в мировые лидеры разработчиков ПО. А он тебе: "Вы к кому, а документики предъявите?" и значится документики проверил, со списочком сотрудников сверился и в журнальчик тебя занес. Благолепие, ибо враг не пройдет.
Но не все так просто. Прихожу на работу, просит записаться в журнале. Документов при этом не спрашивает. И непонятно мне тупому, а на кой простите в том журнале записываться? Т.е. если я допустим запишусь как Иванов, а то даже и Сидоров, чего от того поменяется? Явно действо это не для того, чтобы злобных ворогов, желающих наши мега разработки притырить, не пущать.
Тут особо умные с мест воскликнут: "так это чтобы вас распи... пересчитывать и проверять сколько вы времени на работе проводите, раз уж сколько вы работаете вообще хрен посчитаешь."
Выкрики эти мы осудим как нецензурные, но суть их рассмотрим пристальнее.
На каждом этаже у нас демонические закрывашки на дверях, открываются они исключительно по лепестрическим пропускам, и время, что мы на работе проводим, с помощью этих супер устройств считается и в БД складывается.
А вот эта мега-амбарная книга у мОлодца на первом этаже это чего? Типа дублирующая система на случай выхода из строя основной?
Чудно все это и непонятно.
PS: и все бы было ничего, ибо большинство охранников вменяемые люди, и тоже понимают весь идиотизм этой ситуации. Но всегда найдется один особо резвый (и в данном случае он естественно нашелся), который исковыряет весь мозг своим "записывайтесь"-"расписывайтесь". Причем если утром это не напрягает, записался и хрен с ним. То вечером, когда хочется уже до дому добраться, ковыряние в его каракулях в поисках своей фамилии, чтобы отметить уход, мягко говоря не воодушевляет.
Про редактор для блога
Поставил себе Zoundry Raven для писания в блог. Ибо Opera несмотря на то, что уже 9.62 с гугловым блогом работает через известное место, а интернет эксплорер хоть и работает, но мне надоел. Да и вообще писать сообщения в этом малюсеньком поле ввода как-то не бодрит.
В целом вроде вполне себе ничего, ну т.е. все что надо есть, плюс еще куча какой-то пурги, которая, наверное, кому-то нужна, но мне лично ее назначение не понятно. Несколько расстраивает размер - 44 МБ. Мягко говоря функционал не настолько огромен. Вопросов почем такое большое нет, написано все это на python. Вот зачем это написано на python - это вопрос.
Функционал вообще какой-то странный, т.е. вот, например, вполне приятно рассортировть сообщения по tag (ну мне то на хер не надо, но, в принципе, вполне допускаю, что кому-то да). И в программе такой функционал есть. Но вместо списка tag-ов заделана какая-то хрень разноразмерно-разноцветное нечто - по результату тихий ужас под кодовым названием вырви глаз.
Заделан список линков из сообщения блога, для чего это и кому это надо совершенно не понятно.
Конечно, все это от того, что я ни фига не понимаю во всем этом хозяйстве, под названием "ведение блога". Но скорее всего снесу - мутное оно какое-то.
понедельник, 10 ноября 2008 г.
Про вакансии
С давних времен зарегистрирован на сайте hh.ru (еще, когда он был то ли job.nn.ru, или как-то около того). А тут неожиданно приходит письмо с вакансией.
Все как обычно: тыр-пыр, старший программист, оформление по ТК и т.п. Т.е. там, конечно, масса всякого (когда читаешь вакансии не в режиме поиска размера ЗП и ключевых слов - всегда весело), но последняя фраза, я считаю, просто шедевр.
Исходя из предоставленного ведущим программистом Технического Задания, осуществлять разработку приложения (разработка системы безопасности по типу HIPS)
Оно, понятно, что "Техническое Задание", тем более предоставленное ведущим программистом (кстати, не понятно, почему ведущий программист не с заглавных), сразу становится Новым Заветом. Но вот "по типу HIPS" считаю "чисто конкретно" на пять.
PS. На самом деле, смешно то, оно смешно, только уже плакать хочется.
понедельник, 3 ноября 2008 г.
Про оптимизацию и процессоры
Почитал тут статейку (старую году 2004-го) с сайта AMD про оптимизацию функции memcpy. Исходный вариант с использованием repb переделали на MMX с командой prefetch и прочей ерундой. По статье выходило ускорение в 3 раза, я попробовал получилось ускорение в 2 раза.
Но интересно другое. Я, конечно, слабо разбираюсь во всех этих процессорных заморочках, но вот есть команда repb, которая осуществляет копирование памяти. Производители процессоров прекрасно понимают, что копирование будет втрое быстрее за счет использования MMX. А почему сама команда repb не реализована в процессоре по тем же принципам, и с той же утроенной скоростью?
понедельник, 27 октября 2008 г.
Про создание COM-объектов без регистрации DLL в системе
Как известно, чтобы создать некий COM-объект, надо прежде всего зарегистрировать DLL в которой этот объект реализован. И делается это примерно так
regsvr32.exe SomeCOMObjects.dll
Дальше можно вызывать CoCreateInstance, получать экземпляр объекта и работать с ним.
Однако, иногда возникает желание, пользовать объекты не регистрируя библиотеку, например, когда хочется получить portable версию программы. Один способ я описывал вот здесь. Но к сожалению на Vista этот вариант у меня не прошел или я просто не слишком активно пытался.
Второй вариант создавать объект, загружая соответствующую длл-ку при помощи функции LoadLibrary. Выглядит это следующим образом:
class CCOMDll
{
typedef HRESULT (__stdcall *DllGetClassObjectProc)(REFCLSID rclsid, REFIID riid, LPVOID * ppvObj);
public :
CCOMDll()
: m_sDLLFilePath(_T(""))
, m_hLib(NULL)
, m_pDllGetClassObjectProc(NULL)
, m_pDllCanUnloadNowProc(NULL)
{
}
virtual ~CCOMDll()
{
if (NULL!=m_hLib)
::FreeLibrary(m_hLib);
}
BOOL LoadLibrary(const CString &sDLLFilePath)
{
m_sDLLFilePath = sDLLFilePath;
m_hLib = ::LoadLibrary(m_sDLLFilePath);
m_pDllGetClassObjectProc = (DllGetClassObjectProc)::GetProcAddress(m_hLib, "DllGetClassObject");
return (NULL!=m_hLib);
}
BOOL IsValid() const
{
return (NULL!=m_hLib);
}
//
HRESULT CoCreateInstance(REFCLSID rclsid, REFIID riid, LPVOID* ppvObj)
{
*ppvObj = NULL;
if (NULL==m_pDllGetClassObjectProc)
return S_FALSE;
IClassFactory *pFactory = NULL;
HRESULT hr = (m_pDllGetClassObjectProc)(rclsid, IID_IClassFactory, (void**)&pFactory);
if (S_OK!=hr)
return hr;
hr = pFactory->CreateInstance(NULL, riid, ppvObj);
if (NULL!=pFactory)
pFactory->Release();
return hr;
}
protected :
CString m_sDLLFilePath;
HINSTANCE m_hLib;
DllGetClassObjectProc m_pDllGetClassObjectProc;
};
Понятно, что если делать все по уму надо кой-какую дополнительную обвязку дописать, и выгружать длл-ку тоже следует с осторожностью. Так же не шибко хорошо, когда внутри одного объекта используются объекты из другой библиотеки, которая тоже не зарегистрирована. Т.е. вариант не особо практичный, но в принципе, может кому и пригодится.
Про переезд
Наука доказала, что административное здание может достичь совершенства только к тому времени, когда учреждение приходит в упадок. Эта, казалось бы, нелепая мысль основана на исторических и археологических исследованиях. Опуская чисто профессиональные подробности, скажем, что главный метод заключается в следующем: ученые определяют дату постройки особенно удачных зданий, а потом исследуют и сопоставляют эти данные. Как выяснилось, совершенное устройство - симптом упадка. Пока работа кипит, всем не до того. Об идеальном расположении комнат начинают думать позже, когда главное сделано. Совершенство - это завершенность, а завершенность это смерть.
Сирил Н. Паркинсон. "Законы Паркинсона".
Контора, в которой я работаю, переехала в новое здание. Высокие потолки, большие окна, кондиционеры во всех комнатах (интересно они работают?), здоровые предбанники в туалетах (на взгляд, комната в которой из полезного два унитаза и две раковины, наверное, побольше той где в старом здании мы сидели в вчетвером, а иногда и в впятером), большая столовая (сегодня первый раз за последние полгода удалось прийти в столовую и там было свободное место). Чудесное, чудесное новое здание.
В целом, думаю, это реальный шаг конторы на встречу своей судьбе.
воскресенье, 19 октября 2008 г.
Про хостинг
Перетащил свой DjVu and PDF-ный сайт на новый хостинг. Предыдущий провайдер, который x5x.ru, оказался, мягко говоря, со странностями. Понятно, что сам виноват, в силу слабого понимания всех процессов выбрал не то, что надо, так еще и со знающими людями не посоветовался.
Собственно, этот самый х5х изначально демонстрировал, легкое раздолбайство в работе. Например, есть лог сервера, и его даже можно скачать, но он копится за месяц, по дням не режется и архивируется только в начале месяца, следующего за текущим. Т.е. вариантов два, либо ждать конца месяца, чтобы посмотреть, кто и откуда приходил, а это, мягко говоря, не шибко хорошо, либо каждый день качать файл заново целиком с начала месяца, что бодрит только первую неделю, пока тот файл не перевалит за 20 мегабайт. Побеседовал с тех. поддержкой, они сказали, что архивировать, да еще и по дням для них задача не выполнимая, но зато прикрутили статистику awstat, что, несомненно, здорово, хотя и не совсем то, что было надо.
Ладно, пришлось обходиться awstat плюс добавил google analitycs, которая вполне себе ничего, хотя и не показывает скачки дистрибутивов (или просто я недоразобрался как это правильно сделать).
Сервер валился достаточно стабильно и без дураков, т.е. почта переставала ходить и сайт был не доступен. Отмазы от тех. поддержки какие-то выдвигались и если попинать письмами, то даже работоспособность через некоторое время восстанавливалась. Иногда ни с того ни с сего отлетала генерация статистики, в общем все было достаточно грустно, но терпимо, а к лету все даже как-то более менее наладилось и можно даже сказать стабильно работало.
Последняя капля капнула в понедельник (как не странно 13-го). В половине девятого по Москве, сайт просто отключили, с радостным сообщением:
"Аккаунт ... заблокирован за создание нагрузки на сервер.
Скачивание stduviewer.exe производилось в десятки потоков."
Сказать, что я удивился это ничего не сказать. Да как раз в выходные обновились версии всех программ, соответственно обновились pad файлы и появилось сообщение в rss. Да, без вопросов, нагрузка возросла, народ пришел скачать новую версию фришной программы, но, во-первых, к девяти то вечера напор однозначно должен был спасть (ибо пока основная масса посетителей Россия + Украина, которые приходят с 8 утра до 9-10 вечера), во-вторых, ладно, сервер мегахостера не выдержал напор качающих полуторомегабайтный файл, но для чего же отключили почту и фтп? А отключили все целиком, хттп, почту, фтп, и контрольную панель сайта. На вопрос "отчего так?" Ответ был такой: "Блокируется весь аккаунт, а не что-то конкретное." Считаю правильная придумка.
В целом стало понятно, что нормальных технических специалистов у провайдера нет, потому что нормальные, и нагрузку бы разрегулировали, и отключали бы частями. Так же понятно, что и с бизнесом у граждан сильно так себе, ибо раз клиент жиреет его логично доить, а не посылать на хер. Хотя про последнее оставались сомнения. Может, думаю это такая фишка отключить, и самим более дорогой тариф не предлагать, а выморить клиента чуть-чуть, чтобы дошел. Задаю вопрос: "Вы можете перевести мой сайт на более дорогой тариф и разблокировать?" ответа не воспоследовало, пишут какую-то муть про "нагрузку на дисковую подсистему". Ну, они все время любили поделиться своими проблемами, то у них диск сгорел, то вот две с половиной тысячи посетителей за день создали большую нагрузку на дисковую систему.
Спрашиваю второй раз тоже самое - ответа опять нет. Может гражданам просто на фиг не упал весь этот бизнес, Может схема работы у них такая, хостить сайты из пяти страниц и тремя посетителями в месяц. Я недопонял. По бритве Оккама склоняюсь к варианту, что просто туповаты они для бизнеса (кому не рассказывал про данный случай, первый вопрос был "они дебилы?").
В конечном итоге со стороны "технической поддержки" поступило предложение
"Вы можете использовать дополнительные скрипты для лимитирования одновременных скачиваний Вашего файла, чтобы не создавать подобных нагрузок."
Вариант сам по себе отличный, а если учесть, что и фтп и контрольная панель у сайта отключены, то скрипты я по всей видимости должен был залить телепатически, ибо вариант с "записать на флешку и выдвинуться штурмовать датацентр в САСШ" я сразу отмел как не конструктивный.
В конечном итоге сайт разблокировали, что еще раз утвердило меня в мысли, что ребята минимум с легкой придурью, ибо никаких скриптов я добавлять, естественно, не стал, а заплатил за хостинг в другом месте и перевез сайт, но пару дней продолжал создавать "нагрузку на дисковую подсистему".
Единственное, что я сделал правильно во всей этой истории с хостингом, это не стал регистрировать доменное имя, через этих "бизнесменов", как они не уговаривали. Зарегистрировал бы через них, думаю, проблем было бы сильно больше. А так все обошлось малой кровью.
пятница, 10 октября 2008 г.
Про Opera 9.6
Поставил новую Oper-у, наверное, что-то изменилось в лучщую стороны... но похоже скрипты в этом блоге лучше работать не стали, жаль.
суббота, 30 августа 2008 г.
Про оптимизацию
Оптимизация дело полезное и нужное.
Продолжаю ковыряться в H264 декодере. Доковырялся до расскодирования ключевого фрейма, но получается медленно, решил пооптимизировать.
Итак, оптимизацию делал в двух направлениях, во-первых, перевел кой-какие куски кода на MMX/SSE, во-вторых, раскидал код по тредам для работы на нескольких ядрах.
Жизнь как обычно весела. Потратил неделю на перевод под MMX/SSE (ну правда чистого времени затратил часа три, если б еще кто-то дал мне три часа поработать только над этим, не отвлекая по разным проблемам), еще неделю пытался оптимизировать чтение из битового потока с арифметическим декодером и еще десять минут на многопроцессорность.
Так вот по результатам, ковырянием с битовым потоком уменьшил время декодирования на 5%, перевод под SSE уменьшил еще на 20%, а раскидывание по потокам в 2.5 раза. Что еще раз подтверждает тот факт, что прежде чем заниматься ковырянием мелочей надо попробовать максимально простые варианты.
воскресенье, 24 августа 2008 г.
Про программное обеспечение
Такое впечатление, что писатели программного определения, уже полностью положили на пользователя все, что им удалось положить, т.е. во-первых, лепят абы как слепилось, во-вторых, творят чего хотят, считая, что машина пользователя предназначена исключительно для их программного продукта.
История номер раз.
Надо было пооптимизировать код, поставил CodeAnalyst от AMD. Он предложил встроиться в студию, чего же бы и нет подумал я и согласился. Все прекрасно работает (интерфейс правда страшнее атомной войны и мягко говоря не шибко удобный ну да интерфейс у таких программ вторичен). Итак все прекрасно работает только в статус строке у студии теперь крутится какой-то анимированный значок, что мягко говоря раздражает. Через пару часов значок это задрал по полной, а analyst, как выяснилось вполне достойно может быть заменен расстановкой ATLTRACE и комментированием части кода. В связи с чем решил этот самый analyst снести, и снес. После чего студия перестала запускать проекты на Debug и залечилось это только откатом к restore point. А ведь AMD воплне себе не мелкая контора и даже, наверное, кто-то тестирует ПО перед выпуском.
История номер два.
Поставил себе Corel - то что при установки оно ломится за чем-то в интернет, это полбеды, но вот то, что оно запускает виндовый сервис, убиение которого приводит программу в неработоспособное состояние, как-то удивляет. Т.е. это вот зачем? Я понимаю, когда сервис запускает антивирус или файервол, да мало ли программ которым это реально надо, но векторному редактору оно для чего?
История номер три.
Пользую Oper-у как основной брозер. Кешь хранят в одной папке, у меня на сегодня 40 000 файлов, ясный день, что оно начинает мал-мала тормозить - выгружается по пять минут. Когда делали вот так они думали? Скорее всего нет.
Все это вызывает изумление, да.
воскресенье, 27 июля 2008 г.
Про движок блога
Хороший движок, но написание прошлого сообщения меня утомило.
Во-первых, размер поле ввода маленькое - расчитано на короткие сообщение, а не на развернутый рассказ. Во-вторых, чтобы вставить форматированный код (что C++, что ASM) пришлось помучаться. И, в-третьих, весьма актуально была бы возможность делать "spoiler" как в MSDN, чтобы скрывать/раскрывать код (свой вариант я прикрутил, но чего-же теперь каждый кому понадобится такая функциональность должен делать ее сам?)
Если писать программу для работы с блогом - было бы не плохо реализовать эти опции, правда, чтобы их поддержать надо еще шаблон подправить.
Про MMX, SSE и оптимизацию
Вводная
Продолжаю делать H264 декодер. Надо соответственно сделать обратное преобразование блока 8х8 коэффициентов в 8х8 кусок плоскости (можно назвать это IDCT, но это будет не совсем правда, потому что там от косинусов осталось мало, а получилось что-то вроде Адамара, но не в этом суть). В спецификации H264 вся эта хрень осуществляется за 6 шагов (ну или за 7, как считать, может даже и за 8, для нашего текущего разговора это опять же не важно). Решил, что это хороший повод освежить свои навыки работы с ММХ и SSE.
Я уже как-то пытался попользовать эти мега расширения, но получилось достаточно смешно.
Дома у меня тогда стояла MSVS 2003 Standard. а Standard он очень хороший, только вот опции оптимизации компилятора в свойствах проекта он включить не дает (ну или я как обычно где-то, чего-то не нашел). Но я чего-то про это не особо задумывался. Соответственно, набросал кусок кода на С++, потом сделал код с той же функциональностью под SSE, сравнил скорость, и возрадовался. Разница была где-то раз в десять (естественно в пользу SSE). Правда радовался я до момента пока не скомпилил тот же тест на работе, где стояла MSVS 2003 Prof. Оказалось, что компилятор оптимизирует так же хорошо, как и я. Только у меня процесс оптимизации занимает два часа, а у него пару секунд. Но там задачка изначально, плохо ложилась на SSE, так что эксперимент был не слишком чистым.
Возвращаясь к H264. Здесь все очень красиво, преобразования с матрицей 8x8 (в матрице элементы типа short) плюс первые три шага используют только сложение вычитание строк этих матриц, как векторов. В общем, если не распробовать эти MMX с SSE здесь, то уж не понятно, где их и пробовать.
Формулировка задачи
Разбираться со всеми шагами сразу есть смысл только, если пишешь декодер, а для поиграться с MMX и SSE достаточно разобрать один шаг.
Итак, на входе матрица
short arBufferSrc[8][8];
Мы эту матрицу преобразуем, результат помещаем в новую память (можно собственно и на месте крутить, но оно только усложняет код, а мне этого на данном этапе не хотелось бы). На С++ это выглядит так:
short arBufferSrc[64];
short arBufferCPPDst[64];
short *pBufferSrc = arBufferSrc;
short *pBufferCPPDst = arBufferCPPDst; memset(pBufferCPPDst, 0, 64);
for (int i=0;i<8;i++)
{
pBufferCPPDst[0 * 8 + i] = pBufferSrc[0 * 8 + i] + pBufferSrc[4 * 8 + i];
pBufferCPPDst[1 * 8 + i] = -pBufferSrc[3 * 8 + i] + pBufferSrc[5 * 8 + i]
-pBufferSrc[7 * 8 + i] - (pBufferSrc[7 * 8 + i]>>1);
pBufferCPPDst[2 * 8 + i] = pBufferSrc[0 * 8 + i] - pBufferSrc[4 * 8 + i];
pBufferCPPDst[3 * 8 + i] = pBufferSrc[1 * 8 + i] + pBufferSrc[7 * 8 + i]
-pBufferSrc[3 * 8 + i] - (pBufferSrc[3 * 8 + i]>>1);
pBufferCPPDst[4 * 8 + i] = (pBufferSrc[2 * 8 + i]>>1) - pBufferSrc[6 * 8 + i];
pBufferCPPDst[5 * 8 + i] = -pBufferSrc[1 * 8 + i] + pBufferSrc[7 * 8 + i] +
pBufferSrc[5 * 8 + i] + (pBufferSrc[5 * 8 + i]>>1);
pBufferCPPDst[6 * 8 + i] = pBufferSrc[2 * 8 + i] + (pBufferSrc[6 * 8 + i]>>1);
pBufferCPPDst[7 * 8 + i] = pBufferSrc[3 * 8 + i] + pBufferSrc[5 * 8 + i] +
pBufferSrc[1 * 8 + i] + (pBufferSrc[1 * 8 + i]>>1);
}
Все вроде понятно (кому не понятно, тот соответственно бросает читать, и идет пробовать себя в менеджменте, там, по слухам, еще и платят больше). Отметим один важный момент, на каждом шаге цикла мы используем данные только из i-го столбца, и результат так же будет помещаться в i-ом столбце.
Все работает, код нам потом пригодится проверять результаты работы MMX-шного и SSE-шного вариантов
Оптимизация с использованием MMX
Принцип оптимизации простой. Если в исходном коде мы работали с одним столбцом за раз, то, используя MMX регистры, мы можем обработать сразу 4 столбца. Выглядит это примерно так:
short arBufferSrc[64];
short arBufferMMXDst[64];
short *pBufferSrc = arBufferSrc;
short *pBufferMMXDst = arBufferMMXDst; memset(pBufferMMXDst, 0, 64);
__asm
{
mov eax, pBufferSrc
mov ecx, pBufferMMXDst
mov edx, 2
$loop:
movq mm0, qword ptr [eax]
movq mm1, qword ptr [eax + 4*16]
paddsw mm0, mm1
movq qword ptr [ecx], mm0
movq mm0, qword ptr [eax]
movq mm1, qword ptr [eax + 4*16]
psubsw mm0, mm1
movq qword ptr [ecx + 2*16], mm0
movq mm0, qword ptr [eax + 3*16]
movq mm1, qword ptr [eax + 5*16]
movq mm2, qword ptr [eax + 7*16]
psubsw mm1, mm0
psubsw mm1, mm2
psraw mm2, 1
psubsw mm1, mm2
movq qword ptr [ecx + 1*16], mm1
movq mm0, qword ptr [eax + 1*16]
movq mm1, qword ptr [eax + 3*16]
movq mm2, qword ptr [eax + 7*16]
paddsw mm0, mm2
psubsw mm0, mm1
psraw mm1, 1
psubsw mm0, mm1
movq qword ptr [ecx + 3*16], mm0
movq mm0, qword ptr [eax + 2*16]
movq mm1, qword ptr [eax + 6*16]
psraw mm0, 1
psubsw mm0, mm1
movq qword ptr [ecx + 4*16], mm0
movq mm0, qword ptr [eax + 1*16]
movq mm1, qword ptr [eax + 5*16]
movq mm2, qword ptr [eax + 7*16]
psubsw mm2, mm0
paddsw mm2, mm1
psraw mm1, 1
paddsw mm2, mm1
movq qword ptr [ecx + 5*16], mm2
movq mm0, qword ptr [eax + 2*16]
movq mm1, qword ptr [eax + 6*16]
psraw mm1, 1
paddsw mm0, mm1
movq qword ptr [ecx + 6*16], mm0
movq mm0, qword ptr [eax + 1*16]
movq mm1, qword ptr [eax + 3*16]
movq mm2, qword ptr [eax + 5*16]
paddsw mm1, mm2
paddsw mm1, mm0
psraw mm0, 1
paddsw mm1, mm0
movq qword ptr [ecx + 7*16], mm1
add eax, 8
add ecx, 8
dec edx
jne $loop
emms
}
Все чудесно, чтобы было еще чудеснее надо кое-чего подоптимизировать, но вначале промеряем время и порадуемся нашим способностям в использовании технологий десятилетний давности.
Замеры скорости
Понятно, что отмерить время выполнения одного преобразования не представляется возможным, по причине и его крайней малости, поэтому, мы будем выполнять наши куски по 1 000 000 (одному миллиону) раз. Так же, чтобы никто нам не помешал, выставим побольше приоритет текущему процессу (SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);) и не забудем вернуть его в нормальный по окончанию работы.
А как Вы будете непосредственно время измерять - вариантов, масса сами придумаете.
А я пока расскажу про свои итоги. Вариант номер раз, C++ код - время выполнения миллиона преобразований составляет 111 мс. Вариант номер два, оптимизация под MMX - 24 мс. Я считаю, что это очень достойный результат оптимизации.
Чтобы улучшить этот и без того прекрасный результат надо немного подумать, и, во-первых, не загружать данные в регистры из памяти по два раза, а, во-вторых, развернуть цикл. Регистров для этого вполне хватает, я пробовал. Если все это проделать вместо 24 мс мы получим 20 мс и это хорошая плата, за легкое напряжение мозга.
Основное что нам надо запомнить на данном этапе, это то, что при использовании MMX скорость увеличилась в 4-5 раз. Перейдем теперь к SSE.
Оптимизация с использованием SSE
Принцип оптимизации тот же что и с MMX, только теперь мы будем обрабатывать все 8 столбцов за раз. В данном случае представленный код уже прооптимизирован (в меру моих скромных способностей), на предмет исключения повторной загрузки из памяти в регистры.
short arBufferSrc[64];
short arBufferSSEDst[64];
short *pBufferSrc = arBufferSrc;
short *pBufferSSEDst = arBufferMMXDst; memset(pBufferSSEDst, 0, 64);
__asm
{
mov eax, pBufferSrc
mov ecx, pBufferSSEDst
movdqa xmm0, [eax]
movdqa xmm2, xmm0
movdqa xmm1, [eax + 4*16]
paddsw xmm0, xmm1
movdqa [ecx], xmm0
psubsw xmm2, xmm
movdqa [ecx + 2*16], xmm2
movdqa xmm0, [eax + 2*16]
movdqa xmm2, xmm0
movdqa xmm1, [eax + 6*16]
psraw xmm0, 1
psubsw xmm0, xmm1
movdqa [ecx + 4*16], xmm0
psraw xmm1, 1
paddsw xmm1, xmm2
movdqa [ecx + 6*16], xmm1
movdqa xmm0, [eax + 1*16]
movdqa xmm1, [eax + 3*16]
movdqa xmm2, [eax + 5*16]
movdqa xmm3, [eax + 7*16]
movdqa xmm4, xmm0
movdqa xmm5, xmm1
movdqa xmm6, xmm2
movdqa xmm7, xmm3
psubsw xmm6, xmm1
psubsw xmm6, xmm3
psraw xmm7, 1
psubsw xmm6, xmm7
movdqa [ecx + 16], xmm6
paddsw xmm4, xmm3
psubsw xmm4, xmm5
psraw xmm5, 1
psubsw xmm4, xmm5
movdqa [ecx + 3*16], xmm4
movdqa xmm6, xmm2
psubsw xmm3, xmm0
paddsw xmm3, xmm6
psraw xmm6, 1
paddsw xmm3, xmm6
movdqa [ecx + 5*16], xmm3
paddsw xmm1, xmm2
paddsw xmm1, xmm0
psraw xmm0, 1
paddsw xmm1, xmm0
movdqa [ecx + 7*16], xmm1
emms
}
Меряем для этого кода время аналогично тому, как делали для MMX - получаем 19 мс. Ага. Прирост относительно MMX варианта, прооптимизированого для работы с памятью, 5%. Упс. Но, как выясняется, столь скромный результат связан с тем, что у меня AMD Athlon, на Intel-овском процессоре получилось ускорение на 50% (соответственно, для MMX получили 17 мс, для SSE - 9 мс). Выводы делать не буду, собственно, для меня понятно, что надо пользовать SSE, если возможно, потому что и 5% тоже хлеб, а 50% это уже и масло.
Надо сделать одно замечание по поводу SSE.
Для загрузки данных из памяти в регистры мы используем оператор movdqa, для него есть аналог movdqu, если использовать его, то вместо прироста скорости относительно MMX мы получим спад. Однако, чтобы использовать movdqa и не получить Run time error, исходные данные должны быть выровнены в памяти к 16 байтам. Это можно сделать либо автоматически:
__declspec(align(16) ) short arBufferSrc[64];
либо выделяя памяти побольше и подравнивая руками.
Заключение
Итак, MMX и SSE оптимизация не представляет сложностей, все работает на задаче, которая к этой оптимизации хорошо подходит. Относительно исходного C++ варианта использование SSE дает нам ускорение от 5 раз в худшем случае, до 10 раз в лучшем.
пятница, 25 июля 2008 г.
Про термины
Чем отличается руководящая должность от ответственной?
Правильно, на руководящей - руководят, на ответственной - отвечают.
Иногда эти должности совпадают, т.е. сам наруководил, сам отвечаешь.
А иногда нет, один руководит, а другой отвечает за то, что наделал под руководством первого.
вторник, 15 июля 2008 г.
Про спецификации
Пытаюсь заделать H264 декодер, соответственно, разбираюсь со спецификацией плюс скачал пару опенсырцовых исходников, чтобы контролировать процесс и сравнивать их результаты со своими.
А надо отметить, что я парень запасливый и спецификаций у меня штуки три от разных дат. Собственно сегодня довелось сравнить.
Итак на картинке кусок трех спецификаций, сверху вниз:
1. Draft от 7-14 марта 2003 года
2. Prepublished от марта 2005
3. Насколько я понимаю, окончательный вариант, от ноября 2007
Причем судя по всему, рабочий вариант - второй. Много думал.
понедельник, 7 июля 2008 г.
Про iPod shuffle
Собственно думал много написать, но время позднее, потому "буду краток"(с).
iPod shuffle - удобный агрегат, с хорошим дизайном, делающий все, что мне надо от плеера.
iTunes, которую впаривают для закачки файлов на тот самый iPod shuffle - убогое говно, спроектированное и реализованное людьми, с триппером мозга.
И не имею ни малейшего желания понимать, что iTunes это много больше, чем uploader для железного плеера. Мне другого варианта закачать файлы на shuffle компания, с жеваным яблоком вместо логотипа у которой я тот плеер купил, не предложила.
Судя по тому, что пишут в интернет, я отнюдь не одинок в оценке ситуации.
Если людям, на MacOS приходится пользоваться подобным софтом, я им искренне сочувствую.
воскресенье, 6 июля 2008 г.
Про документацию (продолжение)
На этот раз без лишних размусоливаний. Как известно, сейчас chm уже не так моден как раньше, а модно что-то на подобии MSDN желательно еще и встроенное в это самое MSDN.
И собственно тот набор xslt, которые я рекламировал в предыдущем сообщении, генерируют набор html и кое-какой дополнительной ерунды как раз, чтобы компилировать ее при помощи MSHelp 2.0. Я попробовал - тоже не плохо. Не очень понятно как оно при этом с портируемостью на разные машины, но думаю, что если и сложнее чем с chm, то не намного.
Значит план действий такой.
Заходим в MSVisual Studio, главное меню, File\New\Project\, в появившемся диалоге смотрим есть ли в дереве папка Other Projects\Help Projects\, а в ней вот такие вот шаблоны проектов:
Если их там не оказалось. Качаем Visual Studio .NET Help Integration Kit 2003. (Это ссылка на тот, который для MSVS 2003, для MSVS 2005 тоже есть, и google наверняка знает где.)
Ставим эту милую приблуду. Она встраивается в Visual Studio. Теперь можно создать проект Help-а. Создаем, добавляем туда все html и прочую ерунду, аналогично тому как мы делали для chm. Компилируем. Дивимся на результат.
пятница, 4 июля 2008 г.
Про документацию
Решил, что совсем неплохо было бы задокументировать то, что есть на данный момент в STDU Viewer. А как минимум COM-объекты (конечное приложение документировать особого смысла нет)
В результате хотелось получить, что-то похожее на MSDN (потому что мне нравиться MSDN, ага).
План действий такой.
Этап первый
Обрабатываем исходники doxygen-ом. Только генерим не html (он получается не совсем такой какой хочется), а xml.
Здесь надо учесть, что doxygen не очень хорошо понимает макросы типа STDMETHOD и т.п., а так же испытывает проблемы с такими ключевыми словами как __interface, которые используются в attributed dll-s. А у меня dll-ки именно что attributed.
Большая часть проблем решается стандартным для doxygen способом - в конфигурационном файле, прописываем параметр PREDEFINED. Получается что-то вроде:
PREDEFINED = "DECLARE_INTERFACE(name)=class name" \
"STDMETHOD(result,name)=virtual result name" \
"PURE= = 0" \
. . .
К сожалению, это не решает все проблемы. Например, при описании интерфейса в attributed dll у нас имеются строчки типа:
[id(200), propget] HRESULT PageFormat([in] long Index, [out, retval] long *pVal);
В реализации (классе наследованном от этого интерфейса), это будет выглядеть уже так
STDMETHOD(get_PageFormat)(long Index, long *pVal)
а после замены doxygen-ом макроса STDMETHOD(get_PageFormat) на virtual HRESULT get_PageFormat, мы получим нормальный метод, но этого метода нет в интерфейсе, соответственно, в документации отобразиться не правильное наследование, ну и пошли поехали проблемы.
Для решения пишем простенькое консольное приложение, и прописываем его в качестве параметра INPUT_FILTER в конфигурации doxygen-а. Для каждого файла документации doxygen вызовет этот фильтр, передав ему в качестве параметра путь к файлу, а мы в программе будем читать файл построчно, подправлять то, что нам надо и выдавать строчку на выход при помощи printf.
С первым этапом все.
Этап второй
Если все прошло гладко, то в результате работы doxygen мы получили набор xml файлов.
Теперь надо преобразовать их в html я пользовался набором xslt шаблонов вот отсюда (там кстати есть add-on под Visual Studio, вот только он под VS2005, а я, на своих проектах, до сих пор сижу на 2003-ей и перелезать особого смысла не вижу).
Чтобы применить шаблоны к xml нам понадобиться какая-нибудь программа, осуществлющая эту затейливую операцию. Правильнее всего воспользоваться nsxlt.exe, как это предлагается на сайте где брались xslt шаблоны, а можно написать свою.
Итак запускаем, применяем, получаем набор html-файлов.
Этап третий
Он самый короткий, создаем chm файл. Можно ручками (но лучше таки программно) создать проект, добавить туда все html, полученные на предыдущем этапе, и не забыть css и картинки. Компилим с помощью hhc.exe. И наслаждаемся.
Теперь немного лирических замечаний.
Чем хорош способ?
Во-первых, способ хорош тем, что он легко автоматизируется. Я для себя написал, небольшую оболочку, которая позволяет
1. загрузить конфигурацию doxygen, добавить/удалить файлы по которым будем строить документацию, сохранить конфигурацию.
2. запустить последовательно doxygen, и программу конвертирующую xml в html.
3. сгенерировать проект для создания chm (чтобы не добавлять html руками) и запустить chm-компилятор.
Т.е. практически все на автомате.
Во-вторых, система позволяет документировать код, не отвлекаясь от его написания. Не писать комментарии в коде можно только в случае, если уверено полагаешь, что после того как код написан и сдан, его уже никогда не придется править (более точно никогда не придется править тебе :) ). Такая наивность жестоко наказывается реальностью. Если же детство уже прошло, то комментировать код будешь так или иначе, и совсем не сложно приучить себя комментировать его с учетом синтаксиса doxygen.
В-третьих, то что получается в результате, лично мне, очень нравится.
Чего пока не хватает?
Надо прикрутить автоматическую или полуавтоматическую генерацию оглавления в chm файле. Думаю это не сложно сделать, но пока руки не дошли поковыряться.
Надо посмотреть возможность добавить страницы с общим описанием, т.е. не привязанным к конкретным классам, методам и т.п. Тоже пока просто не пробовал.
Надо несколько упорядочить описания. Пока на главной странице все свалено в один список, интерфейсы, классы, причем из всех длл-к. Это не шибко удобно. Мысли про варианты решения есть, но надо пробовть.
пятница, 20 июня 2008 г.
Про руководство
Цитата вот отсюда:
Искусство руководства есть серьезное дело. Нельзя отставать от движения, ибо отстать - значит оторваться от масс. Но нельзя и забегать вперед, ибо забежать вперед - значит потерять массы и изолировать себя. Кто хочет руководить движением и сохранить вместе с тем связи с миллионными массами, тот должен вести борьбу на два фронта - и против отстающих и против забегающих вперед.
Понятно, что контекст важен, да, но и в отрыве смотрится не плохо.
пятница, 13 июня 2008 г.
Про торговые марки
Увидел тут рекламу по телевизору. Причем видел ее сто раз, но щелкнуло в башке впервые. Интересно как ребята: Eclipse vs Eclipse между собой разруливают? Или аудитории совсем не пересекаются? :)
Google кстати "голосует" за софтовый Eclipse, что, в общем, не удивляет, нет.
Про Opera 9.50
Поставил себе новую оперу (версия 9.50). Вроде стала пошустрее. Грузится быстрее, и закрывается быстрее. Предыдущая версия выгружалась просто дико долго. Переделали дизайн, но есть возможность скачать скин, который приводит все в исходное состояние. Писать в блог все равно из нее невозможно. Но, в принципе, стало лучше.
четверг, 12 июня 2008 г.
Про работу
Все таки оптимальнее всего иметь несколько задач. Причем разнонаправленных. У меня сейчас, например, их в общей сложности штук 10. С утра вот пытался понять как лучше заделать jpeg энкодер. Начитался спецификацию, понял что с ходу ничего не придумывается, отложил, начал прикручивать новые опции в STDU Viewer. С одной стороны мозг там чего-то в фоне шуршит за jpeg, но и время за зря не тратишь полезное чего-то делаешь. Не было бы другой задачи, все равно ничего бы не написал, лазил бы по интернету или худ. лит. какой читал.
понедельник, 9 июня 2008 г.
Про skin-ы
Вот кто бы мне объяснил, что это за мода такая во всех программах втыкать скины. Причем, что не программа, то тихий ужас. Сегодня скачал очередного уродца, вроде полезные вещи делает, но даже разбираться не стал, ибо выглядит как сон обкуринного наркомана. Нет, конечно, есть некоторые вещи, которые в стандртном виде уже не смотрятся. Ну там менюшки лучше на мой вкус когда плоские, панели инструментов опять же. Для меня примером отличного функционального дизайна является микрософтовская студия (причем 2003-я в 2005-ой и 2008-ой тоже мягко говоря не все нравится). А все вот эти потуги дизайнеров, которые позавчера закончили художественную шарагу, вчера изучили книжку Photoshop for Dummies (в переводе надмозга, и не всю, а только первые 20 страниц), зато имеют необхватных размеров художественный вкус, и готовы порвать любого, кто с этим не согласится. Так вот их потуги, они меня лично не радуют. Потому что гавно получается, назовем вещи своими именами. Причем зачастую настолько неудобоваримое, что до функционала уже и не добираешься, просто физически тяжело одновременно работать и блевать.
И вот этот вот продукт жизнедеятельности дизайнеров мутным потоком льется со всех сторон и ни конца ни края ему не видно.
пятница, 6 июня 2008 г.
Про программы для чтения книг
Понадобилось тут книжки почитать художественные. Они сейчас в основном в FB2 формате. На своей Nokia я пользую FBReader - доволен. Ничего лишнего, но все что надо есть. Главный плюс - можно указать каталог на диске из которого автоматически соберутся книжки в дерево по автору и по сериям внутри автора. Для Nokia - программа на пять.
Решил найти себе чего-нибудь и для домашнего компьютера.
FBReader есть под Windows, но он как бы мультиплатформенный и соответственно дизайн общий для всех, и под WindowsXP он мне не понравился. Но программа хорошая, под Nokia самое оно.
ICE Book Reader - вот, кто бы мне объяснил, зачем так делать? Программа под одну платформу - Windows. При этом вместо того чтобы использовать стандартные контролы, приделали какой-то мегаинтерфейс - страшный как моя жизнь. Но этот мегаинтерфейс он только для части программы, а другая часть реализована на стандартных контролах, но и здесь авторам удалось сделать так, что без слез не взглянешь. Создать свою библиотеку с деревом книг, сортировкой по авторам и т.п. вроде как бы и можно, но пять минут потыкав мышкой, мне этого сделать, не удалось, а разбираться было лень. Да и на интерфейс этот дикий дольше смотреть сил не было. Снес.
CoolReader - хороший. Вот выбрать папку, чтобы он из нее все файлики в библиотеку собрал, не позволяет. А по одной, книжки открываются вполне, так что на нем и остановился. Только вот выделить и скопировать текст нельзя, что совершенно не удовлетворительно.
Haali Reader - и эта мне тоже понравилась, я ее еще жене на HP-шный Pocket ставил - вполне рабочий вариант. Настроить папку, чтобы по ней построить список книжек, нельзя. Плюс, программа изначально делалась для WinMobile, что накладывает отпечаток на интерфейс для большого Windows. Это не шибко портит дело, правда не стандартные OpenDialog-и выглядят странно, плюс почему то не запоминается папка из которой последний раз открывалась книга. Но, в принципе, для КПК-шек программа самое оно.
В общем, пока для домашнего компьютера подходящей программы не нашел, хоть сам пиши. Ужас какой-то.
четверг, 5 июня 2008 г.
Установил Warcraft на Nokia
Поставил себе на таблетку (которая Nokia N800) второй Warcraft в какой-то линуксовой реинкарнации. Ностальгирую. На мой вкус одна из лучших игр за всю историю. Считаю три часа времени на установку потрачены не зря. Полный восторг. Хотя играть наверное не буду - времени нет.
воскресенье, 1 июня 2008 г.
Про регистрацию COM объектов при помощи манифестов
Одна из проблем возникающая при попытке сделать "portable" версию некоторой программы, это использование основным exe-файлом COM-объектов.
COM-объекты обычно реализуются в виде dll-файлов, которые регистрируются в системе примерно так:
regsvr32.exe SomeCOMObjects.dll
На самом деле вся регистрация сводится к прописыванию в реестре ключей со списком GUID-ов и ссылками на путь к SomeCOMObjects.dll.
Понятно, что теперь, чтобы программа заработала на компьютере отличном от того, где она установлена, не достаточно утащить туда только exe-файл. В рамках нашей задачи создания portable версии программы, которую можно будет носить на внешнем винчестере или Flash Drive, неплохим вариантом решения будет следующие действия:
1. На внешнем носителе создаем папку для программы и копируем туда, непосредственно exe-файл и все используемые им dll-файлы с COM-объектами.
2. Создаем два bat-файла (или, например, два vbs-файла): COMDllRegister.bat и COMDllUnregister.bat в первом для каждой dll прописываем
regsvr32.exe SomeCOMObjects.dll
во втором
regsvr32.exe /u SomeCOMObjects.dll
Приходя на новый компьютер, запускаем вначале COMDllRegister.bat, потом саму программу, работаем, а перед уходом запускаем COMDllUnregister.bat. Если кроме COM-объектов никаких других привязок в системе у программы нет, то все работает замечательно.
Какие минусы у данного способа?
Минусы очевидны. Если в системе уже были зарегистрированы COM-объекты используемые программой, с которой Вы работаете (известно, что COM это в том числе и способ разделения кода и многие программы используют одни и те же COM-объекты, например, DirectX это исключительно набор COM-компонентов). То при запуске первого bat-файла Вы перенаправите пути с Dll-файлов, расположенных на компьютере, на Dll-файлы на вашем внешнем диске, а после запуска второго, эти COM-объекты из системы исчезнут, что может отрицательно сказаться на работоспособности программ на этом компьютере.
Понятно, что есть варианты решения данной проблемы, например, осуществлять проверку, не зарегистрированы ли уже GUID-ы в реестре, и если да то не регистрировать их, и не разрегистрировать те Dll, которые регистрировали не Вы. Все это понятно, и в принципе, реализуемо.
Но есть способ лучше. Он подробно, с примерами, расписан в статье Registration-Free Activation of COM Components: A Walkthrough.
Суть этого способа сводится к тому, чтобы вместо регистрации COM-объектов в реестре системы, использовать manifest-файлы. Таким образом, в том числе можно использовать в программе вместо dll-зарегистрированной в системе свою.
Итак, что надо сделать.
1. Для каждой dll, содержащей COM-объекты надо создать manifest-файл. Можно это сделать вручную (предварительно придется зарегистрировать dll, а затем воспользоваться утилитой OLE/COM Object viewer), можно воспользоваться утилитой mt.exe из Visual Studio 2005. В результате должен получится набор manifest-файлов примерно такого содержания
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="STDUCore.X" version="1.0.0.0"/>
<file name="STDUCore.dll">
<comClass
clsid="{2BB2E135-4B81-4840-B7CD-A744DD236AB0}"
threadingModel = "Apartment"/>
<comClass
clsid="{1740E2A8-ACF7-4930-B6DF-5D0C85E874DA}"
threadingModel = "Apartment"/>
<typelib tlbid="{A11D2AA5-3D39-448E-B9D0-177A73707C98}" version="1.0" helpdir=""/>
</file>
<comInterfaceExternalProxyStub
name="ISTDUImage"
iid="{3905360D-3C87-498C-93D2-27E002B941B1}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{A11D2AA5-3D39-448E-B9D0-177A73707C98}"/>
<comInterfaceExternalProxyStub
name="ISTDUTransform"
iid="{721B21ED-7BCD-4127-9EFF-6C06AA95FE31}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{A11D2AA5-3D39-448E-B9D0-177A73707C98}"/>
</assembly>
2. Необходимо создать manifest для основной программы, он будет выглядеть как-то так
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type = "win32" name = "client" version = "1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="STDUCore.X" version="1.0.0.0" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="STDUDjVuFile.X" version="1.0.0.0" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="STDUPDFFile.X" version="1.0.0.0" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="STDUTiffFile.X" version="1.0.0.0" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="STDUViewer.X" version="1.0.0.0" />
</dependentAssembly>
</dependency>
</assembly>
STDUCore.X, STDUViewer.X и т.п. это имена файлов manifest для соответствующих dll.
3. Теперь собираем все dll-файлы, основную программу, и manifest-файлы в одну директорию - "portable" версия программы готова.
Выше в качестве примера используются куски manifest-файлов для "portable" версии STDU Viewer
Какие минусы у данного способа?
Во-первых, не всегда возможно определить, какие COM-объекты из каких dll-файлов использует конкретная программа. Во-вторых, мне так и не удалось заставить работать этот способ под Windows Vista, что скорее всего это связано с UAC (но нельзя сказать, что я сильно старался). И, наконец, создание manifest-файлов в ручном режиме, для серьезной программы, мягко говоря, работа не простая, и не шибко веселая.
суббота, 31 мая 2008 г.
Про рост shareware
Наткнулся тут на высказывание, которое показалось интересным
"Если не сожрали в момент выхода на рынок, почему должны сожрать потом? Как правило, дохнут шароварщики по другой причине - решают стать "как большой", нанимают кучу программеров и сейлов, десять программеров работают хуже одного отца-основателя, но ЗП жрут немерянно, сейлы какое-то время поддерживают рост путем все увеличивающихся расходов на маркетинг, потом контора начинает падать. При этом выясняется, что за несколько лет игр с наемными программерами продукт почти не развивался, а конкуренты худо-бедно продвинулись, первоначальный запал пропал и бежать вдогонку сил нет. Усе."
С одной стороны, все очень правильно (правда тут надо учесть, что 99 из 100 шаровар загнется еще до того момента, как появится возможность кого-то нанять).
Но есть и другой момент. Дохнут на мой взгляд, не от того, что "десять программеров работают хуже одного отца основателя", а от того, что работать все это продолжает в том же самом режиме, что и когда "отец основатель" хреначил в одно рыло. Т.е. в самом по себе расширении ничего дурного нет, дурное оно в расширении, без изменения процессов производства.
Т.е. здесь ты обходился без тех. задания и оценки времени разработки, потому что тех. задание было в голове (ну в крайнем случае в виде 10 пунктов в notepad), а время оценивать было не надо, фитчи которые не успевал сделать просто резались на ходу. Там комментарии в коде были не нужны, да и code style был один - тебя устраивающий. А когда программистов стало 10, пожелание, "сделайте вот это", вместо тех. задания, выливается в то, что делают в лучшем случае что-то похожее, в худшем вообще не пойми что. А отсутствие предварительной оценки времени разработки, приводит, к чтению форумов и повышению общего образовательного уровня программистов, а отнюдь не к быстро сделанному коду.
четверг, 29 мая 2008 г.
Про "portable" программы
Все в этом мире как известно развивается по спирали. Далее хочу привести пример, такого развития, с некоторыми отвлечениями и как обычно банальными выводами.
Итак. Вспоминаем славные времена, когда деревья были большими (хотя тенденция к их уменьшению уже прослеживалась), винчестеры маленькими, а про всякого рода USB Flash Drive и прочие полезности никто еще не знал. В то время происходил переход прогрессивной части народонаселения с MS-DOS на Windows 95 (с промежуточной остановкой в районе 3.11). Те кто может объяснить, что нарисовано на копке Save в большинстве программ, так же наверняка вспомнит, как обстояли дела с установкой программ под MS-DOS. В большинстве случаев дела обстояли крайне просто. Папка с программой просто копировалась с одного компьютера на другой, а иногда и копировать ничего было не надо, запускали прямо с дискеты.
С появлением и развитием Windows такой стиль жизни стал не моден. Программы стали хранить кучу всякой нужной им ерунды в системном реестре, а наиболее продвинутые стали использовать COM объекты, и о запуске на любом компьютере с дискеты постепенно пришлось забыть.
Однако, время не стоит на месте, и все возвращается к тому откуда началось. Возвращение это проявляется в двух вариантах, во-первых, с развитием интернет, некоторые из приложений переродились в интернет варианте, неплохой набор таких сервисов есть, например, у google. Во-вторых, как я понял не так давно (до меня вообще все доходит крайне медленно), многие жаждут иметь "portable" версию программы. Ибо даже на флешку объемом 8 ГБ, можно положить практически полный набор программ, которыми пользуешься в повседневной жизни. Что позволяет быть очень даже мобильным, без всякого ноутбука весом пару килограмм. Я уже не говорю, о каком-нибудь внешнем винчестере размером 1.8'. А на подходе еще и SSD девайсы.
Это как обычно была преамбула, и лирическое отступление на предмет пофилософствовать.
Теперь некоторые размышления на тему.
Тема вебприложений меня волнует крайне слабо. Т.е. оно, конечно, очень здорово, но даже отметая всякого рода проблемы с безопасностью, на данном этапе развития интернета в России, максимум, чем я сам могу пользоваться это web-почтой, остальное пока в наши каналы пролазит со скрипом.
А вот тема "portable" программ вполне себе ничего. И имеется минимум два варианта почему оно нравится. Первый, это именно мобильность, т.е. ходить с винчестером и на любом компьютере иметь, весь набор нужных приложений (причем настроенных так как надо), крайне приятная перспектива. Второй, удобство возникающие при перестановке системы, ибо на данный момент, после того как на компьютер взгромоздился WindowsXP, а для всего железа, которое имеет место быть в этом самом компьютере, установлены драйвера (этот этап сам по себе навевает уныние). Начинается установка всего нужного софта. Процесс может затянуться часов на 6-7, и нажатие кнопки Next, выбор директорий и перезагрузка повергает лично меня в полное уныние. А завершается все это настройкой софта под себя (там фонт поменять, здесь панель инструментов вытащить).
Вообщем наличие "portable" версии на мой взгляд сугубо плюс, для любой программы.
Минусы правда тоже имеют место быть. Например, на данный момент нет никакой возможности Word таскаемый на флешке, привязать на открытие doc файлов на компьютере в который эта флешка вставлена. Для случая когда "portable" софт нужен только, чтобы не переустанавливать его каждый раз при переустановки системы, эта проблема решается одним reg файлом. Но этот случай вообще достаточно тривиален, и поддается хорошей автоматизации.
А вот случай с работой с внешнего носителя, намного интереснее в плане технического решения, и если интерес как обычно не пропадет, можно попробовать набросать тех. задание на разработку софтинки для решения этой задачи. Мысли есть, надо их только собрать в кучу, четко сформулировать и результат подергать на предмет потенциальных проблем.
пятница, 23 мая 2008 г.
Пара цитат
- Ну, а что вы предлагаете перспективным исследователям? Возбуждение? Новизну? Волнение от прикосновения к неизвестному? Нет! Вы предлагаете повышенную плату и уверенность в отсутствии проблем.
А. Азимов. "Ленни".
- "Нам нужен не всякий программист, - сказал горбоносый. - Программисты - народ дефицитный, избаловались, а нам нужен небалованный".
- "Да, это сложнее", - сказал я. Горбоносый стал загибать пальцы:
- "Нам нужен программист: а - небалованный, бэ - доброволец, цэ - чтобы согласился жить в общежитии..."
- "Дэ, - подхватил бородатый, - на сто двадцать рублей".
- "А как насчет крылышек? -- спросил я. -- Или, скажем, сияния вокруг головы? Один на тысячу!"
- "А нам всего-то один и нужен", - сказал горбоносый.
А. и Б. Стругацкие. "Понедельник начинается в субботу"
Ну второе то уже закончилось, один программист сейчас мало кому нужен даже, если он может ради интереса, за одни выходные написать на ассемблере компилятор с языка Lisp для Palm Pilot'а (с) Спольски (хотя пяток таких программистов до сих пор могут составить вполне удачную компанию). А первое может и излишне романтично, но думаю верно и сейчас.
Только деньгами и прочим "соцпакетом" можно заманить и удержать исключительно тех, кто желает сидеть на жопе ровно. Но сидя трудно двигаться вперед, можно только утрамбовывать почву и удерживать позиции.
Скучновато.
понедельник, 19 мая 2008 г.
Парадокс Абилина
наткнулся на одном из форумов rsdn.ru
Парадокс Абилина (англ.): Бывает, что люди принимают решения основанные не на том, что они сами хотят, но на том, что они думают, что другие хотят. В результате получается, что каждый делает что-то, что никому на самом деле не нужно.
"Парадокс Абилина" относится к области тимбилдинга, и его более точное определение: "Обманчивый успех единодушного принятия решения в команде". Это такой феномен когда народ собирается совместно обсуждать какую-то проблему, но при голосовании не руководствуется собственной логикой, и в итоге все единогласно поддерживают какую-нибудь фигню.
Очень верное замечание, да. У самого что-то похожее в голове вырисовывалось, но как обычно "все уже украдено до нас"(c)
А вывод для меня очень простой, когда добавляешь в программу функционал полезный тебе, то он полезен минимум одному человеку, когда добавляешь функционал, который как ты думаешь полезен многим, готовься к тому, что он не нужен никому.
пятница, 9 мая 2008 г.
Про формат DjVu
Хочется слегка упорядочить свои мысли про DjVu. Чем и займусь.
Почему-то DjVu всегда сравнивают с PDF, что, на мой взгляд, не корректно. Потому что специфика использования PDF и DjVu совершенно различная.
Единственное предназначение DjVu - это хранение отсканированных изображений. Причем не абы, каких изображений, а, если говорить упрощенно, печатного текста. И в этой нише он отлично работает. Но на этом применимость DjVu заканчивается.
Если начинать сравнивать DjVu с другими форматами, то надо в качестве оппонента выбирать многостраничный TIFF с каким-нибудь CCITT4 внутри. Потому что задачи, выполняемые тем и другим весьма похожи. А с PDF сравнивать глупо. Возможность хранить отсканированные документы в формате PDF, это, мягко говоря, далеко не все, что PDF умеет. Т.е. просто это не то для чего PDF предназначен и для чего он изначально разрабатывался. Такое использование PDF с родни забиванию гвоздей сковородкой, в принципе, можно, но не очень удобно и сковородку жалко.
Но вернемся непосредственно к DjVu и рассмотрим подробнее, что у него внутри такого, что делает его настолько привлекательным для хранения отсканированных изображений.
А внутри у него реализована одна простая идея, которая называется алгоритм JB2.
Задумаемся, как лучше всего сжать печатный текст? Правильно, лучше всего разбить его на символы, каждому символу поставить в соответствие некоторый код. Теперь имея картинки для всех символов в документе, мы, кодируя страницу, создаем список кодов символов и их координаты на странице. Поскольку различных символов в тексте обычно не так чтобы много, и они имеют тенденцию повторяться, то мы резко сократим объем занимаемый изображением.
Посчитаем идеализированный вариант.
Возьмем страницы A4 с 600 DPI в черно-белом варианте (т.е. каждая точка кодируется в один бит). Имеем
8.27' * 600 * 11.7' * 600 = 34 833 240 б = 4 354 155 Б = 4.1 МБ
Это если ничего не сжимать.
А теперь, рассмотрим текст на этой странице. Поскольку мы рассматриваем вариант оптимальный для сжатия алгоритмом DjVu, то текст будем писать одним шрифтом и на одном языке (например, на русском), тогда для кодирования одного символа нам хватит 7 бит. Но мы не будем жадничать и положим 1 байт (тогда можно в тексте использовать 256/66, практически, 4 разных шрифта, если продолжать писать только на русском, ну или русский и английский язык и два шрифта). Для кодирования позиции символа на странице нам достаточно будет 4 байт (достаточно даже и трех, но опять не будем жадничать). Таким образом, для одного символа понадобится 5 байт.
Стандартно на странице умещается примерно 1 800 печатных символов, таким образом, имеем
1 800 * 5 Б = 9 000 Б = 0.00858 МБ
Итого более чем в три с половиной тысячи раз.
Очевидно, что сюда надо приплюсовать картинки для тех 256 символов, которые мы собираемся использовать (они, кстати, займут значительно больше места, чем сам кодированный текст). Но если страниц в документе много, а картинки для символов, будут едины для всего документа, то и этот объем нивелируется.
Конечно же, это описание идеи в чистом виде, практика вносит свои нюансы, которые в формате DjVu с успехом решаются.
Собственно о преимуществе DjVu на этом все.
А теперь про PDF.
В PDF есть схожий кодер JBIG2. Пока мы в своем DjVu to PDF конвертере используем CCITT4 кодирование и размер результирующего PDF файла отличается от исходного DjVu практически на порядок (PDF естественно больше). Интересно будет попробовать заменить CCITT4 на JBIG2 и посмотреть насколько это уменьшит размер PDF. Есть мнение, что если сделать все по уму, то существенно.
пятница, 2 мая 2008 г.
Программы для работы с блогом
Как и собирался посмотрел программы для работы с блогом. Постараюсь описать сей увлекательный опыт.
Итак, задача стояла простая, найти программу для работы с блогом. Требования к этой программе были не шибко великие. Во-первых, естественно, программа должна работать под Windows (здесь есть одно отвлечение, но о нем может быть позже). Во-вторых, программа должна быть бесплатной. Платные варианты смотрелись поверхностно на предмет "скоко же оно может стоить", без всяких намерений покупать.
Особых требований по функционалу не выдвигалось, потому что на данный момент слабо представляю, чего можно потребовать в этом плане.
На странице по верхней ссылке, программ удовлетворяющих моим незатейливым критериям было четыре штуки.
1. NBlog - интересно, плюс исходники, плюс любимый CodeProject. Но к сожалению прогамма на отрез отказалась логиниться к этому серверу. В комментариях к статье на CodeProject что-то про эту проблему есть, но я пока не разбирался.
2. w.blogger - не понравилось, т.е. по функционалу может самое оно, но не понятно чего там народ намутил с визуальной частью. Какие-то свои самопальные меню, смотрятся как тихий ужас, плюс у части контролов выставлен не понятный шрифт, в котором нет русских символов.
3. Zoundry - не понравилось. Опять вполне допускаю, что функционал вполне достойный. Но коллеги программисты, с чего Вы взяли, что в микрософте (не самой мелкой компании) дизайнеры и специалисты по юзабилити тупее вас? Не надо выдумывать свой интерфейс - все уже украдено до вас. Или это не попытка выдумать интерфейс, а просто вообще не понимание, что такое интерфейс? или это такие инструменты выбраны для создания программы, что получается вот так? В общем, работать с этим мне лично, совершенно не хочется.
4. PowerBlog. Опять тоже самое. Интерфейс страшнее чем моя жизнь. Опять меню дикого вида. Панель инструментов на которой кнопки с 16 пиксельными иконками и подписями, которые мне не удалось убрать, т.е. есть вот и меню то сделано так как мне нравится - плоское, и интерфейс с табами как я люблю, но все это как-то так собрано, что результат убивает на повал. Не говоря уже о том, что тех кто делает программы с инсталляцией, но без деинсталляции, надо в детстве убивать из рогатки.
Итого. Программы, которая бы понравилась не нашел.
Зато появилось две идеи, применительно к shareware.
Первая.
Часто в шароварном сообществе возникают беседы вида. "Зачем писать программу при наличии бесплатных аналогов?" "Все ниши заняты, везде куча софта и платного и бесплатного и с открытыми исходниками, как заработать на хлеб насущный?" Так вот сегодняшний поиск мне лично показал, что все эти разговоры - ерунда. Вот, пожалуйста, 4 бесплатных программы. Одна из них просто не работает, а остальные... И вот тут есть еще одна мысль. Весь вопрос в том на кого нацеливать программу. На профессионального блогера, который зарабатывает этим деньги? Ну, в таком случае может он и возьмет одну из бесплатных, ему важен функционал, а к интерфейсу... поработаешь пару недель без остановки, притрешься к любому интерфейсу, абы только не падало часто, и все было более или менее удобно. А если рассчитывать на какого-нибудь чудака вроде меня, тогда уже "красявасти" выходят на первый план, ибо функционал, то мне не особо какой нужен, но развлекаться хочется в красивой обстановке. И я думаю, что ниш таких, где бесплатные аналоги есть, но выглядят ужасно, ниш таких просто завались. Это даже безотносительно того, что функционал у платного, чаще всего побогаче, чем у бесплатного.
Все на самом деле, конечно, не так просто, и каждому свое, кому "красявости", а кому минимализм и портейбл версия. Но пугаться идти на рынок, где уже есть бесплатные программы, явно не стоит.
Вторая.
Менее глобальная, но тоже про шаровару. Возможно, здесь я заблуждаюсь, в маркетинге я не силен. Но что мешает, сделать нормальную бесплатную программу для ведения блога. Бесплатную, но, во-первых, удобную и с нормальным интерфейсом, а, во-вторых, попросить тех, кто ей пользуется чиркнуть пару строчек в своем блоге и дать на нее ссылку. Работы по созданию такой программы на месяц, а даже если появится сотня другая ссылок на сайт, это же очень даже не дурно, это же не ссылки с файлопомоек. Вот эту мысль надо будет подумать и возможно реализовать.
Про движок
Под оперой писать сообщения в этот блог крайне не удобно.
Во-первых, на панели всего две кнопки "проверка орфографии" (вот она мне сильно нужна, с орфографией у меня полный капут) и "добавить картинку", а под ИЕ их сильно больше. Во-вторых, по Ctrl + Shift поле ввода сообщения куда-то пропадает, что мягко говоря вносит определенный экстрим в переключение с русской раскладки на английскую.
Под ИЕ все вроде получше, но как-то за оперу обидно, она мне нравится больше.
А вот из под N800 работает, но набирать что-либо более или менее серьезное тыкая стилусом в экран можно только от большой безнадеги.
Надо отметить, что работать через браузер совершенно не внушает. Попробую завтрева, будет время, софты вот отсюда может подберу чего.
Первая
Создал таки блог, без четкого понимания зачем это вообще мне надо.
Как обычно разберемся по ходу дела. В крайнем случае буду пользовать как интернет-записную книжку.