Эталонный тест - PullRequest
       17

Эталонный тест

9 голосов
/ 20 августа 2010

Сегодня я делал упражнение по кольцу ниток из книги Programming Erlang и гуглил для сравнения других решений. Я обнаружил, что языковая перестрелка имеет ту же проблему, что и тест . У меня сложилось впечатление, что в этой области Erlang должен быть быстрым, но оказывается, что C и C ++ снова на вершине. Я подозреваю, что программы на C / C ++ не следуют правилам, которые говорят "передавать токен из потока в поток". После их прочтения кажется, что они оба манипулируют некоторой общей памятью и глобальными переменными, что отличается от кода Эрланга, но я могу ошибаться.

У меня вопрос: они делают одно и то же или код C / C ++ концептуально (и быстрее) отличается от кода Erlang?

И еще один вопрос: почему Haskell быстрее, чем Erlang, когда решения очень похожи?

Ответы [ 7 ]

9 голосов
/ 20 августа 2010

В версии C используется LWP, который, я думаю, является библиотекой потоков в пользовательском пространстве.В какой степени это «несправедливо», остается предметом споров: я бы посмотрел на такие вещи, как то, поддерживает ли он настоящий упреждающий параллелизм в том смысле, что вы можете делать блокировку системных вызовов в потоке, не блокируя все остальные потоки (вы можетесделать это в Haskell, можете ли вы в Erlang?).

Потоки Haskell немного легче, чем в Erlang, потому что, как я понимаю, поток Erlang поставляется с локальной кучей (в стандартной реализации), тогда как все потоки Haskellразделите одну и ту же кучу.

6 голосов
/ 20 августа 2010

В конечном счете, передача сообщений на современных машинах осуществляется с использованием некоторой формы разделяемой памяти для передачи сообщений (вместе с блокировками или атомарными инструкциями).Таким образом, все реализации C и C ++ на самом деле делают встраивание реализации передачи сообщений прямо в их код.Подобный тест, который использует быструю библиотеку передачи сообщений в C, также сравниваемую с Haskell и Erlang, можно найти в этой статье: http://www.cs.kent.ac.uk/pubs/2009/2928/index.html (раздел 5.1)

Скорость различных подходовдействительно определяется одновременно задействованными системами времени выполнения.Haskell проделал много хорошей работы в этой области, что опережает Erlang.Конечно, измерение скорости на микро-бенчмарках часто ошибочно и не учитывает такие важные факторы, как читаемость кода.Может возникнуть вопрос: какое из решений в перестрелке вы бы с удовольствием поддержали?

5 голосов
/ 20 августа 2010

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

Что сводится к следующему: у Эрланга на самом деле нет потоков как таковых - у него есть процессы с асинхронной связью. Процессы (преднамеренно) в значительной степени изолированы друг от друга. С одной стороны, это значительно облегчает разработку - в частности, один процесс может влиять на другой только через определенные, четко определенные каналы связи. Под капотом он использует множество хитростей (почти наверняка, включая разделяемую память) для оптимизации своих процессов и использования преимуществ, которые возможны в конкретной реализации / ситуации (например, все процессы, выполняющиеся в едином совместно используемом адресном пространстве). Тем не менее, необходимость скрывать все уловки не дает ему быть столь же эффективным, как что-то вроде версии C, где «уловки» все явные и полностью раскрыты.

Я бы использовал реальную аналогию, чтобы объяснить разницу. Думайте о потоках / процессах как о людях. Эрланг налаживает профессиональные рабочие отношения, где все сообщения тщательно записываются в записках. Версии C и C ++ больше похожи на мужа и жену, которые могут общаться одним словом, которое ни для кого не значит, или даже одним быстрым взглядом.

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

4 голосов
/ 20 августа 2010

Я бы ответил на другой вопрос: как реализована среда исполнения Erlang под капотом?

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

Теперь, почему вы находите настолько странным, что оптимизированная версия C (перестрелка определенно не показывает код среднего уровня)побьет версию Erlang, учитывая, что Erlang добавляет свой собственный уровень сложности / косвенности?

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

С другой стороны:

  • сколько времени ушлотебе понадобится написать свой код?
  • какова твоя степень доверия, что он поступает правильно?не тупик?
  • какой из них вы бы предпочли сохранить?

Иногда «быстрее» просто не стоит затрат.

4 голосов
/ 20 августа 2010

почему Haskell быстрее, чем Erlang, когда решение очень похоже?

Haskell GHC - это скомпилированная, оптимизированная для собственного кода реализация языка с очень быстрыми потоками. Как правило, это намного быстрее, чем Erlang / HIPE. У Эрланга нет монополии на легкие нити: -)

2 голосов
/ 20 августа 2010

не соблюдает правила

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

Теперь посмотрите на производительность тех же программ, измеренных с помощью другой конфигурации времени выполнения и отметьте, насколько это важно -

SMP quad core 
1.0 C GNU gcc #3    4.16    4.17    16,952  607   100% 0% 1% 0%
4.2 Haskell GHC     17.99   17.42   4,020   307   100% 1% 1% 1%
7.5 Erlang HiPE     31.12   31.13   10,504  273   0% 0% 0% 100%

No SMP one core
1.0 C GNU gcc #3    4.16    4.16    16,952  607   1% 0% 0% 100%
1.4 Haskell GHC     5.89    5.89    3,204   307   0% 0% 0% 100%
2.6 Erlang HiPE     10.64   10.63   9,276   273   0% 0% 0% 100%
1 голос
/ 24 августа 2010

В этом тесте нужно отметить одну вещь, что нужно пройти только один токен. Это означает, что на практике это просто однопоточная программа чтения и записи из / в память.

Я ожидаю, что результат будет другим на многопроцессорной машине (или в кластере), где потоки / процессы должны передавать M токенов в некотором случайном порядке.

Хм. Также дайте разработчикам эталонных решений равное количество часов для завершения их решения. Тогда я ожидаю, что Эрланг выйдет на первое место (или, по крайней мере, приблизится к вершине).

...