27 июня, 2009

Future Evolution of High-Performance Microprocessors

Довольно интерестное видео о тенденциях развития микропроцессоров. Norm Jouppi из Hewlett-Packard рассказывает о текущих проблемах и о том, что из себя будут представлять микропроцессоры лет эдак через 5-10.

Было много сказано, про power wall и про то, как растущее энергопотребление не дает наращивать частоты. При этом заметно упали темпы снижения базового напряжения, используемого микросхемами. Мне, как программисту, было интерестно в первую очередь другое, — каковы тенденции в развитии микропроцессоров.

Оказалось, что "гонка" за ядрами явление временное, а тенденции смещаются в сторону гетерогенных вычислений. А это значит, что довольно скоро компьютеры будут похожы на... PlayStation. В PlayStation 3 стоит процессор IBM Cell, который по своей архитектуре ближе всего к тому, что называется heterogeneous computing.

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

Во-первых, мы не можем дальше наращивать частоту отдельного исполнителя (процессора/ядра), — слишком большое энергопотребление.

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

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

Выход, по словам инженеров, в том, чтобы в системе находилось несколько "тяжеловесных" энергоемких (если хотите, классических) процессоров, которые смогли бы быстро решать sequential работу, и много маленьких процессоров с коротким pipeline'ом и низкой частотой, которые бы решали параллельные задачи. Из-за своей простоты их энергопотребление может быть очень низким.

На самом деле, это сильное упрощение того, что говорил Norm Jouppi. Поэтому заинтересовавшимся советую посмотреть видео и слайды.

23 апреля, 2009

Groovy remote shell

Я работаю в довольно интенсивно развивающемся проекте. Мы много эксперементируем с разными инструментами. Иногда приходится инструменты разрабатывать самим

Последний инструментарий, который мне пришлось реализовать самому – это удаленный groovy shell. Если вы незнакомы с groovy, то скажу, что это динамический язык работающий на JVM.

Задачей было разработать инструментарий, который бы позволил удаленно дергать некий служебный функционал внутри приложения (запускать переиндексацию, менять настройки thread pool'ов, удалять или создавать обьекты в БД и т.д.). Сначала для этих целей мы использовали JMX. Оказалось слишком сложно и неудобно. Решили сделать удаленный shell, который бы позволял выполнять groovy код в адресном пространстве приложения, что называется, на лету. Что может быть проще, чем получить ссылку на фасад, загрузить пару обьектов и послать им пару сообщений, – прямой канал с приложением в обход всех web-интерфейсов.

Взяв за основу groovysh (стандартный интерпретирующий shell идущий в поставке с groovy) и поигравшись немного с Input/OutputStream, я написал клиента который работает с удаленно запущенной инстанцией groovysh так же, как если бы он был запущен локально (работает автодополнение по tab, command history и т.д.).

Groovy Shell

13 января, 2009

Конец эры закона Мура

Начиная с 70-х годов прошлого века производители микропроцессоров осуществляли экспоненциальный рост производительности, описанный законом Мура. Но достигнув физических ограничений, связанных с резким скачком тока утечки транзисторов и, как следствие, рассеивания тепла, стало понятно — дальнейшее увеличение производительности процессоров существующими техниками невозможно. Еще в 2003 году Intel обещала предоставить 4 ГГц модель. И вроде бы годом позже intel'овцы приблизились к реализации задуманного, — появился процессор с тактовой частотой 3.8 ГГц. Но 4 гигагерцовым "мечтам" так и не суждено было сбыться. А все современные модели процессоров работают на тактовой частоте до 3 ГГц. Индустрия, как мы все теперь знаем, пошла другим путем. Выходом стало увеличение количества процессоров (ядер).

Причем, мне кажется, что Intel давно предвидела что дни гигагерцовых гонок сочтены. Hyper-Threading тому доказательство. Эта технология изначально появилась в архитектуре Xeon, но позже была реализована и в Pentium 4. Это был первый сигнал нам разработчикам, — учитесь распараллеливать. Затем появились многоядерные процессоры. А теперь, Anwar Ghuloum, ведущий инженер Intel, открыто просит разработчиков учитывать особенности SMP архитектуры.
developers should start thinking about tens, hundreds, and thousands of cores now in their algorithmic development and deployment pipeline

Халява кончилась. Дальнейший рост производительности возможен, только путем изменения существующих алгоритмов и их распараллеливания. И именно нам разработчикам придется поставить все эти ядра на службу человечеству. Это и имеют в виду, когда говорят, что наступил конец эры закона Мура.

Справедливости ради надо отметить, что технически закон Мура все же будет выполняться, так как он предсказывает экспоненциальный рост числа транзисторов в интегральный микросхемах. Однако экспоненциального роста производительности при этом наблюдаться не будет. Как такое может быть? На этот вопрос отвечает преемник закона Мура, который и будет вершить бал с этих пор, — закон Амдаля.

Возьмите любую привычную для вас задачу. Если вы заняты в сфере разработки web-приложений — это может быть обработка пользовательского запроса. Представьте, что вы обрабатываете пользовательские запросы в разных потоках (я предполагаю, что так оно и есть). В любом, случае у этих потоков есть, так называемые, точки сериализации. Это участки кода, которые не могут быть выполнены параллельно. Например, некоторые операции в базе данных при использовании транзакций не могут выполнятся параллельно. Shared lock'и и многие виды координации потоков являются точками сериализации. Именно они, — эти противные точки сериализации, являются причиной того, что производительность системы падает при увеличении количества исполняемых потоков.

Попробуйте прикинуть какой процент вашего кода не может выполнятся параллельно. Назовем эту величину (нормированную по единице) фактором сериализации (P). Отбросим пока издержки на синхронизацию памяти. Если фактор сериализации равен 1, то вы не можете ничего распараллелить. Даже появление сотни ядер не ускорит вашего приложения. Если фактор сериализации равен 0, то появление ста ядер ускорит ваше приложение в сто раз (либо позволит решать одновременно сто таких задач). Зная свой фактор сериализации вы можете посчитать, на какой теоретический прирост в производительности (speed up factor), вы можете расчитывать, если в системе будет не одно ядро, а N. Посчитать это очень легко.

Не знаю во сколько вы оценили свой фактор сериализации, но у меня для вас плохие новости. Даже если вы его оценили в 0.1 (10%) — это означает, что вы перестаете эффективно масштабироваться примерно на 10 процессорах (прирост производительности от дальнейшего добавления исполнителей составляет меньше 50% от теоретически возможного). При факторе 0.5 (половина вычислений) добавление пятого процессора в систему ускорит ее максимум на 6% по-сравнению с четырех-процессорной. Говорить об эффективном использовании 8-процессорной машины не приходится. А ведь попадаются очень выдающиеся сервера.

С другой стороны, если взглянуть на каждый отдельно взятый процессор/ядро, то с ростом фактора сериализации его загрузка начинает падать. Происходит это по вполне понятным причинам. Из-за того, что в системе присутствует точка сериализации, которую по-определению может выполнять только один поток, другим потокам в это время просто нечем заняться.

Это немного иронично, но на dedicated серверах из-за этого встает проблема, — как загрузить CPU работой. А выглядит это так. MySQL в какой-то момент времени перестает обрабатывать запросы (делает это очень медленно). Вы заходите на сервер, а там все в порядке: CPU не загружен, памяти свободной куча, i/o в порядке. Но запросы обрабатываются крайне медленно.

Но нет худа добра. Я верю, что мы со временем создадим эффективные и что еще более важно, удобные механизмы для распараллеливания задач. Они уже начинают появляться. У бизнес сектора начинает просыпаться интерес к кластерным вычислениям, что подтверждается появлением таких платформ как Amazon EC2/S3 и Java Stax. Появляются новые языки и инструменты, такие как Scala и Kilim, которые позволяют эффективно работать с concurrency. Получают более широкое распространение уже знакомые методики функционального программирования, которые очень помогают в данном случае. А это все говорит о том, что у нас с вами есть огромное поле для развития и самосовершенствования, чего я вам и желаю.

09 января, 2009

Terracotta v.s. Memcache

В последнее время начали сравнивать Terracotta и Memcache. Мне это сравнение кажется некорректным. Бытует мнение что terracotta - это distributed cache. Это все равно что называть автомобиль "четырехколесным мопедом", только потому, что он может ездить и у него четыре колеса.

Terracotta часто определяют как Network attached memory. И это правда, но не вся. Технически никто не мешает вам использовать terracotta как distributed (или, как его еще иногда называют, clustered) cache. Но тут возникает проблема с HA. В кластере Terracotta всегда есть координатор, который управляет потоком данных. По словам Ari Zilka (одного из основателей Terracota Inc.), именно по этой причине terracotta очень хорошо масштабируется, так как благодаря наличию координатора нет необходимости использовать multicast передачу данных. Однако, наличие координатора означает single point of failure. При использовании memcache SPOF нету, но вам необходимо самому распределять данные по нодам.

Используя terracota вы можете взять LinkedBlockingQueue<Runnable>, пометить его как shared и обрабатывать очередь задач на всех нодах кластера. Вместе с корректной имплементацией распределенных локов мы имеем отличную платформу для распределенных вычислений и возможно даже хранения данных.

С кешем все иначе. Его природа имеет несколько особенностей:

  • потерю кеша приложение должно способно пережить (не требуется HA);
  • при работе с кешем можно обойтись без атомарных его обновлений (не требуются атомарные примитивы и локи);
С первым все должно быть понятно. Если приложение не смогло пережить потерю кеша, значит там хранился оригинал каких-либо данных, а следовательно это уже не кеш. Со вторым немного сложнее. Так как значение в кеше зависит только от внешних данных (данных не хранящихся в кеше), значит невозможны операции когда новое значение кеша зависит от его предыдущего значения. А значит не нужны атомарные обновления.

Memсache отлично подходит для таких сценариев. Ну а если вы решили использовать memcache как storage, а не как кеш, то вы обречены на собственную реализацию атомарного обновления данных, как минимум.

Таким образом, memcache и terracotta - это совсем разные вещи. Первое - это просто network attached memory сервер. И без дополнительного кодирования его можно использовать только для кеширования данных. Второе - полноценная платформа для кластеризации вычислений. Как говорится, know your enemy.

Enhanced null-handling в Java

Как показало голосование по вопросу java 7 language changes, null-handling в java - это самый большой "pain in the ass" из всех, через которые Java заставляет проходить программистов. С другой стороны то-же голосование на devoxxx по вопросу самого популярного языка под JVM, показало, что это Groovy. Видимо, все те, кто привыкли к операторам Элвиса и safe-navigate в groovy, пришли на devoxxx и устроили флеш моб. Вобщем приветствуйте. Proposal определяет 2 новых оператора в языке: null-safe и null-default. Работает так же как и в groovy. Просто и понятно.

Null-safe operator

String a ... ;
String b;

// сегодня
b = a != null
  ? a.substring(10, 2);
  : null;

// завтра
String b = a?.substring(10, 2);

Null-default operator

// сегодня
if ( name == null ) {
  name = "Anonymous";
}

// завтра
name = name ?: "Anonymous";
Лично я ничего против не имею. Давно пора.

8 на 8

Это скриншот с Windows 2008 R2 с запущенным на нем SQLServer.

Примечательна сама загрузка. Загрузить 256 ядер почти на полную одним приложением не так-то просто. У MySQL, например, проблемы начинаются уже с 8 ядрами. У нас в проекте мы это испытали на собственной шкуре.

Как заметил Doug Holland, для того чтобы наблюдать такие полотна графиков, надо иметь по меньшей мере 30" монитор. Task manager плохо масштабируется по колличеству ядер, если вам угодно :).

Так или иначе тенденция налицо. Да здравствует век параллельных вычислений.

25 ноября, 2008

Очередная пачка бреда

В очередной раз наткнулся на гениальное сообщение от spring-ws. Дело было при валидации.
WARN  XML validation error on request: Attribute 'login'
      is not allowed to appear in element
      'ns2:registerRequest'.
WARN  XML validation error on request: Attribute 'login'
      must appear on element 'ns2:registerRequest'.
После таких сообщений я начиню задумываться, а верно ли я выбрал профессию?