2010-01-03 2 views
3

В тесте, который я создаю здесь, моя цель - создать парсер. Поэтому я построил концептуальное доказательство, которое считывает все сообщения из файла, и после нажатия всех их в память я создаю один процесс для разбора каждого сообщения. Пока все будет хорошо, и у меня есть хорошие результаты. Но я мог видеть, что erlang VM не использует всю мою мощность процессора (у меня есть четырехъядерный процессор), на самом деле он использует около 25% процента моего процессора при выполнении моего теста. Я провел встречный тест с использованием C++, который использует четыре потока и, очевидно, использует 100%, что дает лучший результат (я уважал ту же модель очереди erlang).Оптимизация производительности на процессах Erlang

Так что мне интересно, что могло бы «замедлить» мой тест erlang? Я знаю, что это не вопрос сериализации, поскольку я создаю один процесс за сообщение. Я думал, что, может быть, мое сообщение слишком маленькое (около 10 тыс. Каждый), и поэтому большая часть процессов не помогает достичь отличной производительности.

Некоторые факты о тесте:

106K сообщения На Эрл (25% использовали мощности процессора) - 204 мс На мой C тест ++ (100% мощности процессора используется) - 80 мс

Да разница не такая уж большая, но если есть больше власти, конечно, есть больше возможностей для улучшения, не так ли?

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

Обновление:

Woooow! Следуя идее Хасана Сайеда, мне удалось достичь 35 мс против 80 с C++! Это круто!

+0

Непосредственная мысли, знаете ли вы, сколько времени уходит на сканирование файла по сравнению с разбором сообщений. Сканирование по своей сути является последовательным, так что параллелизующий эффект процессов нереста может быть потерян. Это может объяснить, почему ядра не используются. – rvirding

ответ

4

Кажется, что ваш erlang VM использует только одно ядро.

Попробуйте запустить его, как это:

erl -smp enable +S 4 

-smp включить флаг говорит Erlang для запуска системы во время выполнения с поддержкой SMP включено С + S 4 Вы начинаете 4 Erlang планировщиков (1 для каждого ядра)

вы можете увидеть, если у вас включен SMP при запуске оболочки:

Erlang R13B01 (erts-5.7.2) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false] 

Eshell V5.7.2 (abort with ^G) 
1> 

[Smp: 2: 2] говорит, что работает с СПР включен 2 schedu LERS 2 schesulers онлайн

+0

(+1) Это, вероятно, проблема: P. Однако современные балки запускаются с поддержкой SMP нет? –

+0

Да, последняя версия автоматически запускает SMP, но использование 25% -ного процессора указывает, что используется только 1 ядро, поэтому, вероятно, scooterman использует старую версию или может быть скомпилирован без SMP. – filippo

+0

hmmm интересно, что на окнах, по-видимому, SMP был отключен, и я использую не очень-то (R13B1) версию. Хотя теперь у меня больше использования процессора, скорость разбора совсем не изменилась. :(Спасибо, тем не менее. – scooterman

2

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

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

- Обсуждение C++ против Erlang и ваших выводов -

Erlang имеет пользовательское пространство ядра, которое эмулирует много примитивов ядра ОС. Особенно планировщик и блокирующие примитивы. Это означает, что при сравнении стратегии есть некоторые накладные расходы, такие как стратегия, используемая на процедурном языке, таком как C++. Вы должны настроить разбиение своей задачи на каждую запись из пространства реализации (CPU/memory/OS/language language) в соответствии со своими свойствами.

+0

@ Hassan Да, я понял, что вы сказали. Я все еще считаю, что нереститься столько процессов, сколько необходимо, это путь. Я могу сделать несколько парсинга в пакете, как вы сказали, поэтому стоимость создания/уничтожения процесса может быть нормализована к тому времени, когда требуется выполнить синтаксический анализ. Я буду тестировать позже и обновить результаты. И о разности C++, да, также, я это знаю. Я только что сделал контр-тест, чтобы иметь низкий запас, на какую скорость я должен ожидать, я не пытаюсь добиться того же, поскольку сила erlang не в том, чтобы разбираться. – scooterman

2

Вы должны связать планировщик с ядрами процессора:

erlang:system_flag(scheduler_bind_type, processor_spread). 
Смежные вопросы