Archive

Archive for March 28th, 2010

MonoTouch: разработка iPhone приложений с помощью .NET

March 28th, 2010 No comments

Вступление Для разработки программных продуктов для iPhone необходимо погружаться в изучение Objective-C и Xcode IDE. Для многих разработчиков это является стоп-фактором. Особенно это касается .NET разработчиков, которые редко волнуются по поводу управления памятью, указателей и других "сишных" вещей. После анонса MonoTouch, который является частью проекта Mono от Novell) эта ситуация изменилась. Mono – это open-source реализация Microsoft .NET Platform, позволяющая запускать .NET-приложения на любой платформе, включая Apple, FreeBSD, Linux, Uni и других. MonoTouch позволяет запускать приложения на iPhone. Целью данной статьи является предоставить информацию о том, что нужно для начала работы с MonoTouch, а также показать пример простого приложения. Читать полностью

Categories: Uncategorized Tags:

Mac OS X, часть 2.2. Графическая подсистема Quartz. Продолжение.

March 28th, 2010 No comments

Для тех, кто из-за большого перерыва между статьями уже забыл, напомню — в прошлый раз мы начали знакомство с Quartz — графической подсистемой Mac OS X. Я рассказал о том, как в целом устроен Quartz, из каких частей состоит, и за что каждая из этих частей в итоге отвечает, а также показал на примере Mac OS X 10.0 (Cheetah) как собственно был реализован Quartz, и с какими проблемами пришлось столкнуться разработчикам. С проблем-то и начнём.

Основная проблема с Quartz в первой версии Mac OS X заключалась в том, что работало всё довольно таки медленно (помните тест с полупрозрачной консолью и QuickTime-роликом?). Центральному процессору приходилось трудиться за себя и за того парня, выполняя команды рисования Quartz2D, записывая результаты их работы в backing store, а за тем — выполнять композитинг всех окон в финальную сцену. Разумеется, долго так продолжаться не могло, и вот как поступили разработчики Quartz в Mac OS X 10.2 (в версии 10.1 особых изменений в работе Quartz не было за исключением некоторых общих оптимизаций).

Quartz-Jaguar

Как видно из рисунка, теперь Quartz Compositor целиком выполняется на GPU видеокарты. Этого удалось добиться, переделав Compositor в OpenGL-приложение, для которого каждое окно представляло собой двухмерную поверхность, а содержимое backing store для этого окна —текстуру этой поверхности. Эту версию Quartz назвали Quartz Extreme, и она работала только на видеокартах, поддерживавших текстуры произвольного размера (так как окно, по сути, также может быть любого размера) и AGP 2x, для того, чтобы иметь возможность читать содержимое backing store напрямую из оперативной памяти.

Перенос Quartz Compositor на видеокарту сильно разгрузил центральный процессор. Выполнение операций по блендингу больших битмапов — с этим GPU справляется очень и очень хорошо (для этого его и придумали). Более того, центральный процессор перестал заниматься и переносом backing stores из оперативной в видеопамять, а это тогда значило очень много (когда частота системной шины не превышала 133 мегагерца). Возвращась к тесту с полупрозрачным окном терминала и видеороликом: на том же самом компьютере, но со включенным Quartz Extreme, fps видео вообще не менялся, вне зависимости от того, сколько полупрозрачных окон было размещено поверх него. Самые отчаянные экспериментаторы доходили до 25 окон, но fps ролика оставался невозмутимым — 24 кадра в секунду.

Mac OS X 10.3 (Panther) тоже не принесла никаких изменений в работе Quartz (как и 10.1), кроме общей оптимизации. Посмотрим теперь, что произошло в 10.4 под кодовым названием Tiger.

Quartz Extreme отлично справлялся с работой по композитингу backing stores в финальную сцену, однако загвоздка в том, что backing store не заполняется по мановению волшебной палочки — его содержимое сначала кто-то должен нарисовать. Представим, например, окно браузера с текстом, картинками, элементами управления и тому подобным. Если только окно не является полупрозрачным (или находится под другим полупрозрачным окном), трудоёмкость композитинга меркнет в сравнении с вычислительной сложностью задачи отрисовки содержимого окна в backing store. Рассмотрим в качестве примера текст. Каждый из этих символов должен быть растеризован из своего векторного описания в файле шрифта, к этому растру должно быть применено сглаживание, а затем он должен быть помещён на саму страницу с учётом фона (то есть, по сути — должен быть выполнен композитинг для этого конкретного символа внутри окна браузера). Всю эту работу приходится выполнять CPU, так как Quartz Compositor имеет дело с уже заполненными backing stores. Более того, содержимое окна перерисовывается каждый раз, когда, например, меняется его размер или выполняется прокрутка его содержимого. И в этом случае Quartz Extreme ничем не может нам помочь — он просто мучительно долго (в сравнении с CPU) ждёт, пока центральный процессор закончит рисовать в backing store, а затем очень быстро выполняет композитинг финальной сцены и ждёт следующей итерации.

Ещё одна проблема становится видна, если посмотреть на схему работы Quartz Extreme, обращая особое внимание на ширину полосы пропускания (напоминаю, что конкретные цифры приведены исключительно для относительного сравнения) и сопоставляя её с объёмами данных на каждом участке. Результаты вызовов API Quartz2D, по сути, представляют собой большие растровые изображения, которым нужна довольно таки широкая полоса. Сами вызовы Quartz2D довольно маленькие по объёму, и большой полосы пропускания им не надо. На рисунке же мы видим, что самое узкое место (между оперативной и видеопамятью) используется для передачи самых больших объёмов данных (заполненных backing stores).

Наконец, учитывая то, что backing stores обрабатываются на двух разных процессорах (CPU и GPU), с раздельной памятью (RAM и VRAM), можно догадаться, что эта схема работы обладает высокими накладными расходами на синхронизацию. Пока с backing store окна работает Quartz Compositor, приложение рисовать туда не может, и наоборот — Quartz Compositor не может начать выполнять композитинг до тех пор, пока приложение не закончило рисование.

Решение всех этих проблем может показаться очевидным — достаточно поместить Quartz2D в часть диаграммы, где больше всего жирных красных линий — на видеокарту, решив тем самым проблемы с пропускной способностью и синхронизацией. Итак, встречайте — Quartz2D Extreme.

Quartz-Tiger

Глядя на картинку можно заметить, как всё больше и больше задач в Quartz выполняется на видеокарте. Объясняется это очень просто — достаточно посмотреть на величины ширины полосы пропускания между GPU и видеопамятью. Причём, эта величина продолжает расти, и расти гораздо быстрее, чем полоса пропускания между центральным процессором и RAM.

Как мы видим, вызовы Quartz2D теперь выполняются на GPU, а центральному процессору остаётся только отправлять сравнительно небольшие по объёму команды рисования через драйвер на видеокарту. Естественно, не было бы смысла перемещать Quartz2D на видеокарту, а backing stores хранить по-прежнему в RAM, поэтому и они теперь перехали в видеопамять. Помимо того, что теперь отрисованные backing stores передаются по широким шинам между GPU и видеопамятью, разработчики Quartz ещё и существенно снизили задержки на синхронизацию, ибо теперь и Quartz2D, и Quartz Compositor выполняются на одном процессоре (GPU) и пишут/читают из одной и той же памяти (VRAM).

Казалось бы — победа. Однако, как это часто бывает в жизни, всё оказалось не так просто. Во-первых, центральный процессор не всегда передаёт только маленькие команды рисования для Quartz2D. Самый распространённый пример — растровые изображения. Представим ситуацию — изображение на диске, а backing store рисующего приложения — в видеопамяти. Как оно может туда попасть? Напрямую с диска видеокарта читать не умеет, поэтому эту операцию приходится выполнять всё тому же CPU, сначала загружая изображение в оперативную память, а потом передавая её по узкой шине между оперативной памятью и видеокартой. Таким образом, если CPU придётся часто передавать большие растровые изображения, это может уничтожить все преимущества в скорости, которые даёт использование Quartz2D Extreme. Решение оказалось довольно таки простым — такие растровые изображения, будучи переданными на видеокарту один раз, кэшируются в видеопамяти, и затем Quartz использует только локальную копию в VRAM.

Но тут перед нами встаёт другое проявление суровой реальности — видеопамять, к сожалению, конечна, и постоянно кэшировать в ней большие растры не представляется возможным. Что произойдёт, если объёма VRAM окажется недостаточно для хранения всех backing stores, закэшированных битмапов, отрендеренных шрифтов и так далее? Нетрудно заметить, что относительно недавно (в масштабах вечности, разумеется) такая же проблема вставала с другой памятью — оперативной. Решение нам всем хорошо знакомо — виртуализация. Таким же образом поступили и разработчики Quartz — те данные, которые не уместились в видеопамяти, сбрасываются на более медленный носитель — оперативную память. Разумеется, Quartz старается размещать в видеопамяти не любые данные по принципу FIFO, а именно те, которые используются чаще всего. А когда видеопамяти всё-таки оказывается недостаточно, то начинается печально известный «хронический пэйджинг», который знаком каждому, кто пытался запустить какую-нибудь современную ОС на компьютере с 256 мегабайтами оперативной памяти, разве что диск не шумит.

Учитывая всё вышесказанное, какой же выйгрыш даёт применение Quartz2D Extreme (и даёт ли вообще)? Посмотрим на результаты синтетических тестов в следующей таблице:

  Quartz2D
Тысяч операций в секунду
Quartz2D Extreme
Тысяч операций в секунду
Ускорение
Прямоугольник 100×100 40 185 4.6x
Прямоугольник 800×800 2 472 236x
Узор 8×8 42 177 4.2x
Картинка 128×128 32 392 12x
Строка из 12 символов 1,733 4,720 2.7x
Линии 1,700 14,900 9x

В принципе, все результаты являются предсказуемыми, а особенно выделяется тест на заполнение прямоугольника размером 800 на 800 пикселей. По сути, этот тест проверяет, как быстро Quartz сможет нарисовать 640 тысяч пикселей в backing store, пропустить его и другие backing stores через Quartz Compositor и вывести всё это на экран. В предыдущих реализациях Quartz, центральному процессору пришлось бы рисовать этот прямоугольник в backing store, который находится в оперативной памяти, а затем передавать его на видеокарту, чтобы Quartz Compositor мог выполнить композитинг и выполнить вывод на экран; теперь же центральному процессору достаточно передать только одну OpenGL-команду на рисование прямоугольника в Quartz2D Extreme, который отрисует прямоугольник прямо в видеопамять — как раз туда, где его уже ждёт Quartz Compositor. Стоит обратить внимание ещё на одну деталь. Строка из 12 символов рисуется «всего» в 2,7 раза быстрее с помощью Quartz2D Extreme, что показывает, насколько хорошо в Tiger оптимизирована софтверная реализация Quartz2D (без Extreme). Это становится ещё заметнее, если сравнить её с софтверной реализацией Quartz2D в предыдущей версии Mac OS, Panther. Обратимся к результатам теста на рисование линий:

Panther-Situation

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

Tiger-Situation

За 12 миллионами линий в секунду, которые успевает отрисовать Quartz2D Extreme, трудно разглядеть, что тот самый софтверный Quartz2D, который в предыдущей версии был медленнее QuickDraw почти в два раза, теперь стал быстрее его в пять раз. В итоге имеем неплохой прирост производительности в 10 раз.

Ну, а теперь самый животрепещущий вопрос — повысились ли удои? Виден ли этот бешеный рост производительности в реальных приложениях? Так вот — разница вовсе не так заметна, а некоторые приложения стали работать _медленнее_ при включенном Quartz2D Extreme. В чём же проблема? А проблема как раз в кэшировании битмапов в видеопамяти. Дело в том, что Quartz без посторонней помощи не может предсказать (хотя и старается), какие битмапы будут использоваться приложением в ближайшем будущем. Чтобы знать об этом, приложение должно сигнализировать Quartz, какие битмапы ещё будут вскоре использоваться, сохраняя ссылки на них (тут я поясню, что в CoreGraphics — API, которое позволяет получить доступ к функциям Quartz2D — да и во многих других API Mac OS реализован механизм счётчика ссылок). А это прямо противоречит установившейся практике, когда память из под использованных битмапов освобождалась сразу, а потом, при необходимости, изображение снова читалось с диска (тут ещё и хороший дисковый кэш помогал). Однако, с момента выхода Tiger, разработчики приложений для Mac OS X (особенно усиленно работающих с графикой) уже поправили эти моменты, и теперь всё работает, как по маслу.

Вот, пожалуй, и всё, что я хотел рассказать вам про Quartz — графическую подсистему Mac OS X. Самое интересное, что предложенная в Tiger реализация без каких-либо особых изменений продолжает работать и в последней версии Mac OS X — Snow Leopard, много раз в секунду что-то рисуя, копируя, кэшируя, выполняя композитинг и выводя всё это безобразие на экран.

В следующей серии статей мы поговорим об API и инструментах разработчика, которые предоставляет Mac OS X нам, программистам; ну а пока, как обычно, я приглашаю всех к обсуждению статьи в комментариях. Stay tuned!

DevCamp Винница: впечатления, презентации и фото

March 28th, 2010 No comments

Вчера прошел DevCamp Винница и сейчас хочу поделиться своими впечатлениями. Настоящий фурор вызвал доклад Романа "Dependency Injection на примере Unity и nInject" о подходах к написанию хороших проектов (критериями хорошего проекта является возможность масштабирования, тестирования, поддержки). Также хочу отметить доклады о Windows 7 (ohoncharuk), где было показано много фич, о которых никто не догадывался, доклад "Разрабатываем веб-приложения с помощью jQuery" (Eney) и доклад об Exchange 2010. Приятно, что и мои доклады об iPhone и ASP.NET Dynamic Data вызвали определенный интерес. Читать полностью

Categories: Uncategorized Tags:

Своя IT-фирма: итоги рекламы за 3 недели – 2 клиента, а так же о VS2010 Launch

March 28th, 2010 No comments

5 марта я запустил рекламу в яндексе. За все это время было 6 обращений, в т.ч.: – 2 реальных клиента. О них напишу далее; – 1 заказ из Дагестана :) На разработку Java-программы для мобил. После объявления примерной стоимости пропали. – 1 непонятный заказ – какой-то сайт о фразеологии, но после первого созвона сказали что еще будут думать. Скорее всего, вряд ли что-то выгорит. – 1 предложение о сотрудничестве, но явное кидалово – с их стороны только консультации (предлагают разработку ПО для консалтинговых фирм), которые мы, к тому же, еще и оплачивать должны! :) Типа они свою долю вернут после начала продаж. – 1 бонус – дипломник написал и спросил стоимость разработки – ему нужно экономическую часть в дипломе рассчитать :) 5 раз из 6 пользовались формой заказа на сайте. Еще 1 – сразу позвонили на телефон. Теперь о клиентах. Первый – разработка сайта, но крутецкого, типа www.hotelmap.com – сходите, не пожалеете. У нас такого еще нет. Явно просится туда Silverlight, но чертова его малая распространенность! И все бы ничего, но не очень мне пока нравится сам клиент. Опять из разряда "хочу то, не знаю что". С одним таким я уже пытался работать, но в итоге отказался. Попытаюсь все же вытянуть, используя накопленный опыт – разработаю в Axure прототип, разобью на этапы и посмотрим что получится. В конце концов, зато там стоимость проекта ну ооочень прельщает меня :) Кстати, этот клиент сейчас выбирает между мной и еще какой-то фирмой. Как я понял по тону разговора, конкуренты запросили меньше и сроки короче. Но у них есть косяк – они к первой встрече так и не посмотрели ее ссылки, т.е. не подготовились. Я же пришел во всеоружии – узнал даже больше, чем требовалось :) Так что у нее решение на 90% принято уже в пользу меня. Второй – пока не могу сказать, на днях подписываем соглашение о неразглашении. Но проект тоже очччччень интересный. Могу пока сказать только что это будет разработка под Win7 на .Net 4.0 :) Кстати, с такими темпами мы уже можем набирать разработчиков. Пока на удаленку – офиса нет. Если есть у кого желание – пишите на mailbox@nevlabs.ru. Ну и о Visual Studio 2010 Launch Я читаю доклад на этом событии – про перенос Mysql на Sql Server. По этому случаю доработал программу тестирования производительности. Потестировал еще на разных базах. Пока получается примерно такой результат: на маленьких базах и простых запросах Mysql оказывается быстрее. Но только туда добавляются JOIN или что-то подобное, Sql Server уходит вперед. Кроме того, у него гораздо более стабильное время выполнения запроса – у Mysql это время сильно гуляет, особенно с увеличением числа параллельных потоков. Хорошо бы еще провести тест, оптимизировав базы данных, но у меня в этом опыта почти нет, а времени остается мало. Если кто-то подскажет экспресс-меры – буду признателен :) Я сейчас имею в виду настройки самих серверов, а не создание индексов – они уже созданы.

Categories: Uncategorized Tags: