Какая самая маленькая единица работы, разумно распараллеливаться с актерами?

В то время как Scala актеры описываются как легкие, акковые актеры, тем не менее, есть некоторые накладные расходы на их использование.

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

Я ищу общее эмпирическое правило, которое я могу легко применить в своей повседневной работе.

EDIT: Ответы до сих пор заставили меня понять, что меня интересует, пожалуй, фактически обратное вопросу, который я изначально задавал. Итак:

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

Ответы

Ответ 1

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

Итак, сначала вам нужно решить, использовать ли вообще concurrency (что может быть связано с производительностью или правильностью), а затем использовать ли актеров. Последнее очень важно для вкуса, хотя с Akka 2.0 мне нужны были хорошие причины, потому что вы получаете дистрибутивность (вверх и вниз) по существу бесплатно с очень небольшими накладными расходами.

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

Ответ 2

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

Ответ 3

Если в рабочих единицах не ожидается никаких побочных эффектов, лучше принять решение о разделении работы во время выполнения:

protected T compute() {
  if (r – l <= T1 || getSurplusQueuedTaskCount() >= T2)
    return problem.solve(l, r);
// decompose
}

Где:

T1 = N/(L * Runtime.getRuntime.availableProcessors())

N - Размер работы в единицах

L = 8..16 - Коэффициент загрузки, настроенный вручную

T2 = 1..3 - Максимальная продолжительность рабочей очереди после всех краж

Вот презентация с гораздо более подробной информацией и цифрами:

http://shipilev.net/pub/talks/jeeconf-May2012-forkjoin.pdf