Принцип работы нового устройства описал Мартин Маас из Калифорнийского Университета в Беркли. В своей работе он предложил вынести в отдельный блок функцию «сборки мусора», при которой процессор удаляет из памяти ненужные данные. На эти операции тратится от 10 до 35% мощности процессора, но отдельный аппаратный блок выполнит эту функцию эффективнее. Такой элемент занимает мало места и не требует большой мощности.

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

Маас и его коллеги предложили добавить к ЦПУ модуль, который выполнит все три задачи гораздо эффективнее. «Пока приложение запущено на процессоре, этот блок параллельно выполняет сборку мусора», — комментирует Маас, — «это значит, что можно создать систему, где ПО в принципе не занимается сборкой мусора и просто использует доступную память». Маас отмечает, что 10% ресурсов, которые процессор тратит на сборку мусора, могут показаться незначительными, но в глобальном масштабе это даёт ощутимую экономию.

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

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


  1. picul
    13.05.2019 18:56
    +5

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


    1. vedenin1980
      13.05.2019 19:12
      +2

      Раскройте свою мысль, плиз. Что вы тут имеете в виду?

      Языки без сборки мусора, вроде C/C++? Там ПО все равно требуется помнить и обрабатывать удаления объектов. В целом, та же сборка только вручную запрограммированная и с человеческими ошибками. Плюс, все равно ОС должна следить кому и какую память она выдавала и вовремя ее очищять.


      1. andreymal
        13.05.2019 19:24
        +2

        В Rust память автоматически контролируется компилятором без всяких сборок мусора, например. (Но рантаймовые счётчики ссылок тоже есть, разумеется)


        1. vanxant
          13.05.2019 23:40
          +1

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


          1. nrgian
            14.05.2019 00:38

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

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


            Нелогично.

            Смотрите: допустим, нанимаем не студентов, а квалифицированных и дорогих.

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

            И именно поэтому и
            Не очень популярный сегодня подход прямо скажем



          1. agalakhov
            14.05.2019 11:52

            Как человек, уже несколько лет программирующий на Rust продакшн, скажу: вот очень хорошо, что mut приходится отслеживать. Потому что на этом этапе ловятся логические ошибки. Времена жизни объектов, их мутабельность, оказались очень тесно связаны с правильностью самого алгоритма и зачастую ловят грубые ошибки лучше всяких тестов.


      1. picul
        13.05.2019 19:31
        +2

        Мне кажется, Вы смешиваете понятия сборки мусора и деструкции объектов. Разумеется, деструкцию все еще нужно выполнять, и в это, кстати, удобнее всего именно в C++ за счет присутствия RAII. А вот сборка мусора (то есть куча бесполезной работы с памятью и счетчиками ссылок только потому, что никто не удосужился сказать, что объекты временные и их можно сложить на стеке) в C++ отсутствует. Про память и ОС вообще не понял.


        1. tmaxx
          13.05.2019 20:28
          +1

          Мне кажется в статье под «сборкой мусора» имеется в виду «динамическое выделение памяти в куче». То что происходит при malloc() и free(). По умолчанию этим занимается ОС и алгоритмы там далеко не тривиальные. Если в среднестатистической программе таких вызовов много, то отдельный чип сможет немного разгрузить CPU для основного кода.


          1. raid
            13.05.2019 20:44
            +3

            malloc и free — это функции стандартной библиотеки, а не ОС. От ОС они получают страницы памяти через mmap и освобождают через munmap, если говорить про Linux. Что имеется в виду под сборкой мусора в статье, остаётся только гадать.


          1. picul
            13.05.2019 20:47
            +1

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


          1. hssergey
            13.05.2019 20:58

            Видимо да, потому что виртуальные машины Java, JavaScript, Python и так далее с точки зрения операционной системы — это пользовательские программы, и каждая виртуальная машина размещает объекты в памяти и реализует логику GC по-своему. И чтобы вынести их сборщики мусора на отдельный процессор, их надо переписывать, реализовывать какой-то общий механизм сборки мусора, единый для разных виртуальных машин, и уже затем его запускать на отдельном процессоре. И то, не знаю как для других языков, но в Java сборка мусора многоуровневая, и есть так называемая полная сборка мусора, где выполнение основной программы приостанавливается, а сборщик подсчитывает все ссылки и вызывает для нужных блоков delete(). Такую сборку мусора стараются делать как можно реже, чтобы не тормозило лишний раз, но все равно как это реализовывать в отдельном чипе, чтобы не приостанавливать выполнение основной программы, непонятно…


          1. tmaxx
            13.05.2019 21:09

            Мда, мне стоило открыть оригинал прежде чем писать комментарий…

            В статье действительно речь о обычном GC — сборщике мусора в managed-языках (Java, C#, Python). Не очень понятно как планируется сделать аппаратное решение, достаточно гибкое для этого.


            1. rkuvaldin
              14.05.2019 01:34
              +1

              В свое время были в моде процессоры, которые байткод из коробки поддерживали.


  1. staticmain
    13.05.2019 19:10

    GC? В моем уютненьком процессоре? No way!


  1. maxzhurkin
    13.05.2019 19:49

    встроенные в процессоры сборщики
    что за звери такие?


  1. strcpy
    13.05.2019 20:00
    +1

    1. akurilov
      13.05.2019 20:21

      Видимо, не взлетело )


      1. potan
        14.05.2019 17:03

        Не все с первого раза взлетает.
        Сейчас железо сильно подешевело и завязанного на GC софта стало заметно больше. Может в этот раз взлететь.


        1. Gryphon88
          14.05.2019 17:19

          Насколько я понял статью, предлагается единый хардварный GC «to rule them all»: т.е. и для Java, и .NET, и cpp. Но протестировано только для Java. Мне интересно: единый GC без десятилетий боданий по стандартизации вообще возможен?


  1. yarston
    13.05.2019 20:43

    Лучше б научили компилятор автоматически вызывать free();


    1. vanxant
      13.05.2019 23:38

      Так gc оно и есть — автоматическая вызывалка free().


      1. yarston
        13.05.2019 23:56

        Так оно оверхэд вносит, про который и речь.
        Хотя если выделять объекты на стеке, то в С/С++ они удаляются автоматически, без вызова free() / delete() или GC. Но указатель на них нельзя передать за пределы области видимости, в которой они были созданы. Вот если бы компилятор чуть умнее был, и сохранял бы объект при передаче указателя, и сам бы удалял объект, после того, как указатель больше нигде не используется, не нужен был бы GC.


        1. JPEG
          14.05.2019 00:44

          Попробуйте rust.


        1. vanxant
          14.05.2019 03:16

          Выделять объекты на стеке — это для программ типа диодом на ардуине поморгать.
          В реальности у нас давно кругом многопоточность, корутины и асинхронность. Пока вы делаете await, ваши объекты на стеке успеют десять раз протухнуть.
          Посмотрите на мучения ядра Linux с асинхронностью. Нет, не неблокирующим i/o, который они торжественно назвали асинхронностью лет 15 назад, а настоящей, которую вот вроде как «скоро» обещают (при том что в винде оно лет 25 как работает). Там делов-то буквально два байта переслать (код ошибки при вызове функций ядра типа read), никаких там указателей. Проблема в том, что в классическом unix эти два байта хранятся не в стеке конечно, но в статической переменной, которая создаётся ядром при создании потока. Только это не работает для асинхронных вызовов, порядок завершения которых не определён.


          1. yarston
            14.05.2019 09:34
            -1

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


            1. 0serg
              14.05.2019 09:37

              Смещение указателя на стек и есть освобождение памяти на стеке.
              Вы очень плохо разбираетесь в memory management.


              1. yarston
                14.05.2019 09:51

                Я знаю, как работает стек. Думал поисследовать тему автоматического управления без оверхэда, запилить для начала статический анализатор, который бы выдавал предупреждения о неосвобождении памяти для ограниченного числа случаев, потом потихоньку допиливать до покрытия 100% возможных случаев. Удивительно, что никому кроме меня тут это не нужно. Ну да ладно.


                1. 0serg
                  14.05.2019 10:37

                  Если говорить о плюсах, то все созданное на стеке всегда автоматически уничтожается компилятором при освобождении стека. В 100% случаев, т.к. как вам уже написали эта память будет повторно использована в следующем же вызове какой-нибудь функции. Выделение и особождение памяти на стеке сводится к перемещению указателя на стек, поэтому работает очень быстро. Оверхед там равен нулю. В силу этой же причины оставить что-то в стеке после выхода из функции невозможно. Если вы хотите переиспользовать созданный на стеке объект после выхода из функции (= очистки стека) то его обязательно надо скопировать в другую область памяти, например в кучу. Любая работа с кучей — это оверхед, но в основном на выделение памяти, а не на ее освобождение. Умные указатели бывают разные — unique_ptr к примеру дает нулевой оверхед на освобождение памяти (относительно ручного особождения). У shared_ptr оверхед равен одной атомик-операции на копирование и освобождение -. В общем тема там большая и интересная, а вы все велосипед изобретаете вместо того чтобы разобраться как работает то что было создано до вас.


        1. Paskin
          14.05.2019 07:25
          +1

          Указатель на стековые обьекты нельзя передавать за пределы области видимости потому, что при вызовах следующих функций по ходу выполнения программы — их параметры и их локальные переменные располагаются по тем же адресам. А если вы выделяете память в куче а не на стеке — то старый добрый reference counting вполне позволяет передавать такие обьекты куда угодно и при выполнении неких нехитрых правил они будут освобождаться как только будет удалена последняя ссылка.


    1. potan
      14.05.2019 17:06

      Rust умеет. Но это дается не бесплатно, человеку приходится писать так, что бы компилятор мог понять, где это надо делать.
      К тому же это мешает использовать TCO.


  1. Gryphon88
    13.05.2019 21:29
    -2

    Что только люди не придумают, лишь бы VLIW не допиливать, ну или хотя бы не делать независимые ядра под задачу.


    1. AC130
      14.05.2019 01:18

      Если вы знаете способ решить ту же самую задачу лучше, то вы можете написать критическую рецензию на оригинальную статью. Не держите в себе, пусть человек знает что он занимается не тем, тогда он сможет потратить свою жизнь на что-то более полезное.


      1. Gryphon88
        14.05.2019 14:28

        К сожалению, не знаю. Проблемы с управлением памятью есть давно, и примерно столько же их пытаются решить: на уровне языка, на уровне компилятора или его вспомогательных инструментов, на уровне ядра ОС, ну и в железе. Последний способ мне нравится меньше всего: он дорогой, даёт временный буст, который потом приходится тащить в следующие поколения процессоров, а ещё лишняя железка, неподконтрольная программисту, в том числе на уровне ядра, меня банально бесит. Я за решение на программной стороне, пусть даже это и ломает обратную совместимость.


        1. AC130
          14.05.2019 19:36

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


          1. Gryphon88
            15.05.2019 14:29

            Я признаю, что изначально выразился резковато. И статью я читал, мотивация написана про «чем плохи современные GC». Мои мысли перпендикулярны идее статьи: я считаю, что GC вообще не нужен, если стоит вопрос эффективности. Судя по списку литературы, авторы знакомы с этой точкой зрения. Развить эту мысль я не смогу, поскольку не имею достаточных знаний для того, чтобы написать «идеальный» ЯП, а к нему оптимизирующий компилятор и до кучи транслятор с существующих энтерпрайзных ЯП, чтобы идея с восторгом была принята индустрией.


  1. AndrewSu
    13.05.2019 22:39
    -1

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

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


  1. chaynick
    13.05.2019 23:39
    +2

    Шел 2019 год, люди изобретали сопроцессор…


    1. Sly_tom_cat
      14.05.2019 01:12

      … очередной сопроцессор…

      … в давние времена даже DMA умудрялись процессором/сопроцессорм называть…


  1. nerudo
    14.05.2019 10:36
    +1

    Требую назвать его «мусорным сопроцессором».


  1. old_bear
    14.05.2019 10:46

    Маас и его коллеги предложили добавить к ЦПУ модуль, который выполнит все три задачи гораздо эффективнее. «Пока приложение запущено на процессоре, этот блок параллельно выполняет сборку мусора», — комментирует Маас

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


  1. roscomtheend
    14.05.2019 12:44

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


  1. potan
    14.05.2019 13:03

    В Intel iMAX 432 такой был.
    Идея хорошая, но там программа не могла сама создавать указатели и сопроцессор сборки мусора мог отличить указатель от данных. К современным процессорам, программируемым на C, аппаратную сбору мусора корректно прикрутить будет очень сложно.


  1. potan
    15.05.2019 20:16

    A Hardware Accelerator forTracing Garbage Collection
    Видимо идея уже созрела.