Пользователь
0,0
рейтинг
31 января 2009 в 15:41

Разработка → На передовой дизайна виртуальных машин перевод

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



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

Архитекторы виртуальных машин столкнутся с той же проблемой, что и создатели процессоров сегодня — не делай одну вещь быстро, делай несколько вещей одновременно. Поэтому я не верю, что эталоном виртуальной машины есть путь выбранный JVM. Джава не создана для вот такого будущего:

Изображение подглядываем из блога Тоби Арчиани, который украл его у Ульфа Вигера, который взял у Джо Армстронга, который одолжил у Эрика Шагерштерна.
На графике — часть процессора, до которой можно добраться за один такт.

На первый взгляд тяжело оценить преимущества использования виртуальной машины Эрланг. Сборщик мусора работает в мягком реальном времени, в то время как сборщик мусора JVM работает в жестком реальном времени. Компиляция «на лету» достаточно медленная для методов с вычислительной математики и не может «инлайнить»(подскажите правильное слово?) между модулями так как это делает HotSpot. Для неопытных администраторов Эрланг вообще — ужас. Без видимых на то причин начинает поедать процессорное время и память и единственный способ узнать что происходит это влезть в шелл и набирать комманды на какомто эзотерическом языке!

Но все эти проблемы очень мелкие если взглянуть на планы и цели виртуальной машины Эрланг. В начале книги «Програмирование в Эрланг», один из создателей языка, Джо Армстронг, рассказывает об мечте конкурентной модели программирования: ваша программа работает в N раз быстрее на N процессорах. Эрланг в некоторой мере достигнул этой цели используя распределенную модель программирования. Но распределенное программирование сложно: настанет момент когда вы должны будете учитывать стоимость пересылки сообщений в сети, бороться с латентностью, отсутствием сети, падением серверов. И хотя Erlang/OTP предоставляет мощную платформу для разработки распределенных сервисов, многие факторы распределенности оказываются несущественными, когда речь идет об одном сервере с большим количеством ядер в процессоре.

ВМ Эрланга поддерживает SMP планировщик, запущенный в обычном потоке для каждого ядра процессора. Это дает возможность ВМ распределить процессы на несколько процессоров одновременно избегая негативные стороны распределенного программирования. Простое правило Эрланга: создавайте столько процессов сколько хотите — планировщик загрузит ими процессор равномерно.

И хотя всё это красиво и интересно у SMP планировщика есть много узких мест. Все работает прекрасно с двумя или четырьмя ядрами но как только вы начнете увеличивать это число то производительность не только не улучшится но и может упасть. Та же ситуация и в JVM но исходя из того, что такое поведение есть результатом фундаментальных принципов и дизайна этой виртуальной машины, модель конкурентности Эрланга дает создателям значительно больше вариантов оптимизации.

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

Итак, вот тв чем дело: (извини за то что вырезал рисунки из презентации Ульф! Они рулят!)

На этом рисунке было большое лого Эрриксона. Если кто нибудь пожалуется — я сделаю свою версию.


Так выглядит планировщик виртуальной машины Эрланг. Есть много планировщиков, каждый из которых работает в отдельном потоке, и выполняет код из общего потока комманд. Видите слабое место? Посмотрите на эту кучу стрелочек указывающих на одно место! Как же решить такую проблему? Разделять и властвовать:



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



Красная линия — это сегодняшний SMP планировщик с единой очередью выполнения. Синяя линия — SMP планировщик следующего поколения, который будет уже в ближайших версиях Эрланга. Как мы видим, разделение единой очереди действительно помогло, но после достижения некоторого числа ядер производительность снова начинает падать. В чем же дело?

Опять куча стрелок указывающих в одно место! :(

Выделение памяти в Эрланге — еще одна точка блокировки и соответственно слабое звено в масштабируемости системы. Я предполагаю, что Ульф вставил это в свою презентацию потому, что это — очередная задача, которую будут решать создатели Эрланга при разработке нового SMP планировщика.

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

Системы вроде JVM конечно не исчезнут с приходом многоядерного будущего. Подход вроде программной транзакционной памяти может быть успешно использован в JVM особенно с языком вроде Clojure для достижения результатов, в определенных проблемах распаралеливания, лучших, чем модель «ничего общего между процессами» в Эрланге.

Но в общем, я нахожу подход к конкурентности Эрланга более понятным и делающим жизнь программистов легче, пряча всю сложность распределенности на низший уровень виртуальной машины. Этот подход может быть более логичным чем ПТП, особенно если он обретет «человеческое лицо», чего я пытаюсь достичь своим проектом языка программирования на базе виртуальной машины Эрланга — Reia. Но главное — наличие огромного потенциала улучшений производительности виртуальной машины для многоядерных систем, и я надеюсь, что однажды мы таки увидим мечту Джо Армстронга в действии — исполнять программы в N раз быстрее на N процессорах.

P.S. Русский не есть моим нативным языком, поэтому любые исправления или предложения по улучшению читабельности приветствуются. Спасибо за то что дочитали до конца ;)
Перевод: Tony Arciani
Max @keymone
карма
24,5
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (51)

  • +1
    Отличная статья, спасибо!
  • 0
    боттлнек — узкое место
    • 0
      да, такой вариант у меня был но я как то не решался его использовать :) спасибо, исправил
  • 0
    Не программер, но очень понравилось.
  • +1
    «инлайнить»(подскажите правильное слово?)


    если вы перевод просите, то слово «инлайн» переводится «открытая подстановка», правда на мой взгляд «межмодульная открытая подстановка» звучит не так прикольно как «межмодульный инлайн» =)
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        я думаю что нет…
    • +1
      лучше не переводить технические термины, иначе никто не поймет друг друга
      • 0
        говорить на каком-то руглише тоже не всегда приятно… есть ведь красивые слова… «оперативный компилятор», «открытая подстановка», «среда исполнения», «распределение регистров»… так нет же постоянно джит, инлайн, рантайм и регаллок…
        • 0
          Не знаю почему, но согласен с вами ровно наполовину. Если быть точным — в отношении ужасности «рантайма» и «регаллока».
        • 0
          на работе некогда красиво выговаривать «распределение регистров в оперативном компиляторе среды исполнения»

          поэтому «регаллок в джите рантайма»
  • +2
    Поэтому я не верю, что эталоном виртуальной машины есть путь выбранный JVM. Джава не создана для вот такого будущего:

    Конечно, не создана. Она создана для другого: а именно упростить работу с программными потоками как с независимыми друг от друга сущностями, разделяющими общее адресное пространство в одном процессе.

    Ведь JVM сама по себе уже много лет не занимается шедулингом собственных (green threads) потоков, а перекладывает эту работу на системный планировщик (ULE3, к примеру, в FreeBSD 7.1) и библиотеку поддержки выполнения легковесных потоков пользовательского уровня (libkse или libthr с pthreads, к примеру). В Solaris и Linux подсистемы поддержки легковесных потоков (LWP) с нативным SMP-планировщиком MxN давно уже работают.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      императивная модель конечно ближе, но только потому, что был актуальным на протяжении уже многих десятилетий. сейчас же имхо мы увидим сдвиг парадигмы — это неизбежно и это всегда воспринималось и всегда будет восприниматься в штыки.

      java.util.concurrent возможно поможет, но не более чем помог эфир для объяснения природы света.
    • +3
      На самом деле статья — скорее для программистов на эрланге, поэтому в ней ничего нету собственно о преимуществах подхода эрланга, подразумевается что и так все понятно.

      В двух словах поясню: проблема с java.util.concurrent и другими библиотеками с «классическим подходом» ( java как таковая тут особо не при чем, она в рамках этого подхода как минимум не хуже других) — это

      1) тяжеловесность потоков (создание нативного потока, переключение потоков — довольно тяжелая операция)
      2) много данных часто расшарено между потоками — императивный подход этому способствует, и из-за большого количества блокировок программа может простаивать и хреново масштабироваться на большое количество процессоров
      3) благодаря (2) нужно синхронизировать доступ к данным, а для этого используются такие весьма нетривиальные механизмы как мьютексы, condition variables, евенты и пр. При их использовании требуется немало усилий чтоб не допустить дедлоков и прочих приятных вещей, а отлаживать их нелегко.

      В эрланге предлагается для решения проблемы (1) использовать суперлегкие потоки; чтоб обойти (2) он функциональный (хотя не строго — эрланг создавали очень практичные люди, для решения практических задач). (3) решается засчет того что расшаренных данных практически нет (кроме БД и хэш-таблиц), а основной способ общения между потоками — через сообщения.

      Вообще говоря, это конечно создает и некоторые неудобства, и это не единственный способ решения этих проблем (см. еще Software Transactional Memory), но способ вполне рабочий и мощный.
      • 0
        а еще можно пробовать удешевлять создание и переключение потоков на уровне OS или даже ниже, на железе…
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          Тут, кстати, по поводу FutureTask интересный момент. В ерланге потоки это не «запутил, посчитал. закончил», там вообще все потоки. Это сложно понять, объяснить врядли смогу, но попробую :) В общем решил попробовать эрланг, сделать чтото типа дискового кэша, fault tolerant'ного. так вот после ломаний головы как это все организовать архитектурно, осуществить дублирование, взаимодейсвие отдельных частей и пр. и пр. пришел к тому что тупо запускаем 20-50 тыс. потоков, каждый из которых умеет оперировать строго определенным файлом, который знает кто его самого дублирует и кому пожаловатся, если что. И все заморочки архитектуры тутже пропадают. При этом все эти потоки прекрасно обмениваются друг с другом данными, запускают новые когда считают нужно, и не думают о всяких дедлоках, синхронизациях и пр.
          дисклаймер: я сам кучу лет плотно сижу на игле жавы, просто не фанатик.
          • НЛО прилетело и опубликовало эту надпись здесь
            • +1
              Так а какая там нафиг синхронизация? все разделено, всем потокам пофиг на остальных
              • НЛО прилетело и опубликовало эту надпись здесь
                • 0
                  Вот вот, сложно измерить :) к томуже это скорее прототип, кучу оптимизацй не применено (я же говрю что я хотел лишь посмотреть что такое эрланг). но вообще желание измерить есть, так как именно ради этого я затеял эксперимент.
                  но перед этим я долго изучал сколько стоит поддержка стольки потоков, судя по многочисленным статьям и тестам это стоит копейки.
                • 0
                  именно об этих синхронизациях данный топик :)

                  а вообще, об таких вещах не стоит заботится. вы же не заботитесь об том насколько эффективно ЖВМ выделяет вам память или насколько эффективно работает планировщик тех же FutureTasks?

                  заботится об этом надо как только оно станет проблемой производительности
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • 0
                      но ведь виртуальная машина как и любая другая платформа прячет от вас многие реализации и аспекты низкоуровневого программирования, чтоб можно было сконцентрироваться на конкретной реализации многопоточного алгоритма. поэтому я не понимаю что вас беспокоит? Эрланг очень хорош для прототипирования систем — попробуйте и если производительность будет на порядки ниже допустимой(то есть исключая возможность оптимизации до необходимого уровня) рассмотрите другие варианты.
        • 0
          1) Не совсем то — одновременно, получается, может выполняться только несколько FutureTask'ов, по количеству рабочих потоков. Ну и если например один блокируется (соединения к сокету ждет), то следующий за ним выполняться не начнет ведь. То бишь нельзя создать тыщу таких потоков чтобы они взаимодействовали между собой (хотя кстати в Scala это есть).

          2) Разумеется, в java/C++ можно реализовать сообщения, и что угодно. Но ими будет не так удобно пользоваться, а в эрланге есть для этого все средства (прежде всего, pattern matching). Это не просто синтаксический сахар, это заметно упрощает дело.

          3) Можно, конечно, придумать дедлок на сообщениях, но там это таки заметно сложнее.

          Короче, erlang — не замена яве никак, и можно наверное соорудить аналог эрланга в виде библиотеки для явы. Только будет намного более громоздко и менее эффективно — зачем мучаться, если можно взять эрланг сразу (а там интерфейс к яве, если что, входит в стандартную поставку).

          Что касается «навязывания» «правильных» методов программирования параллельных приложений — это нормально, особенно если не ставить цели создать универсальный инструмент. В конце концов, создатели явы в свое время неспроста не стали туда включать перегрузку операторов и множественное наследование из C++, хотя это, безусловно, добавило бы выразительности.
        • 0
          1) тут уже наверное вопрос в совершенности планировщика виртуальной машины.

          2) вопрос глобальный — насколько дешевле будет разрабатывать систему на платформе без готовіх реализаций и без любіх ограничений? насколько высоким будет порог вхождения и насколько больше программистов вы сможете себе позволить?

          3) Эрланг не позволяет написать программу наступающую на дэдлок на уровне доступа к памяти. дэдлок на уровне доступа к процессу вполне возможен, но это проблема где то на том же уровне сложности, что и зацикливание в императивном языке. найти и исправить значительно легче.
      • 0
        Еще кстати немаловажный момент — в эрланге все можно так же легко и непринужденно разнести не только по потокам на одной системе, но и по разным машинам. Авторы (эрланга) последнее время очень любят заострять внимание именно на многоядерности и подобных плюшках, понятно, это модная тема, но все таки распределенность по-моему основной плюс, а вычислительные задачи чисто на эрланге делать не очень с руки: он же заметно медленнее явы, динамический язык все-таки.
  • 0
    «конкурентности Эрланга дает создателям значительно более вариантов оптимизации.» Поправьте пожалуйста.
  • +2
    «сборщик мусора JVM работает в жестком реальном времени


    неподскажите который из? Метроном? Он только IBMовской виртуальной машине…
    В Sun HotSpot AFAIK нет hard real time GC…

    Кстати вы знакомы с компанией Azul? Они уже сейчас делают „железные Java-машины“, в которых число ядер измеряется сотянями… Так что говорить, что Java не готова к многопроцессорному будущему… Несколько не верно =)
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        я думаю статья о технологиях с которыми уже в ближайшем будущем(почти сегодня) будет иметь дело самый обычный программист.
        • НЛО прилетело и опубликовало эту надпись здесь
          • +1
            я тут просмотрел сайт www.azulsystems.com и не нашел никаких цен. обычный программист может позволить себе использовать этот программный комплекс(или это не только программный но и аппаратный?) например дома?
            • 0
              нет, если он, конечно, не БГ…

              с другой стороны у вас дома что 500 ядерная машина и вы на ней на Erlang колбасите?
              • 0
                500 ядерная машина будет и у меня и у вас уже через несколько лет.
                • 0
                  Ну если поставить современную видюху то даже сегодня :)
    • 0
      Тут скорее имелась ввиду не JVM, а сама Java. Автор даже привел в пример Clojure который вроде как готов.
      Вы ведь прекрасно понимаете что ускорить программу в 860 раз перенеся ее с 1просессорной машины на 860 процессорную можно лишь при условии что ее код написан так что там ровно 860 полностью независимых потоков, правильно?
      Так что тут два подхода, или полностью менять VM (ну и язык к ней), чтобы программисту совсем выбора небыло. Или придумать язык для текущей VM который направит в нужное русло (но к сожалению не заставит). Erlang — первый путь, а Scala, Clojure, Fortress — второй.
      • 0
        И что? На Java нельзя написать код, который будет хорошо параллелиться?
        • 0
          Можно, но на порядок проще на clojure и fortres.
          • 0
            разве что синтаксически
            • +2
              А есть чтото важнее? :) ведь не спроста перестали на перфокартах писать код, синтаксис таки имеет значение :)
              Ну а на самом деле, я имел ввиду что какой язык такое и приложение. Не буду приводить яркие примеры популярных языков, и поднимать этим еще один холивар, но думаю вы меня уже поняли :)
  • 0
    я понимаю, что топик достаточно холиварный для жавистов, и я должен признать что не знаю всех деталей реализации JVM и не могу аргументированно защищать позицию автора.

    топик мне показался интересным в контексте информации об ВМ Эрланг, а не Ява — именно поэтому я и решил его перевести.
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Может, конечно может. Но на практике такие программы не встречаются :(
        Вот тут была вроде хорошая машинка, 32 процессора, куча памяти, все дела. Так вот как ни странно лучше работал вариант с запуском нескольких копий приложения, нежели одного, но на все процессоры :(
  • 0
    масштабированостимасштабируемости?
    • 0
      спасибо, исправил
  • +1
    Русский не есть моим нативным языком
    Истинный программист!
  • 0
    Извините но использование термина «жесткое реальном время» в применимости к JVM профанство и дальше можно уже не читать статью.

    • +1
      • 0
        Видно был неправ. Если это есть в Java SE то уже этим они б'ют .NET очень сильно, правда реализация есть только под Солярку и Сюзю.

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