Как сделать этот Java-код распараллеливаемым? Как сделать его облачным? - PullRequest
1 голос
/ 06 декабря 2010

Сейчас я работаю над системой.Это сложная система, но она сводится к классу Solver с помощью метода, подобного следующему:

public int solve(int problem); // returns the solution, or 0 if no solution found

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

List<Integer> problems = getProblems();
List<Integer> solutions = new ArrayList<Integer>(problems.size);
Solver solver = getSolver();
for (int problem: problems) {
    solutions.add(solver.solve(problem));
}
// see what percentage of solutions are zero
// get arithmetic mean of non-zero solutions
// etc etc

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

  1. Скажем, у меня миллионпроцессор ядра и что экземпляры Solver являются поточно-ориентированными, но без блокировки (они неизменяемы или что-то в этом роде), и что все вычисления, которые они выполняют, находятся в памяти (т. е. не происходит никакого диска, сети или других операций).Могу ли я просто заменить список решений на список безопасных потоков и запустить потоки, чтобы решить каждую проблему и ожидать, что она будет быстрее?Насколько быстрее?Может ли он работать за 5 секунд?

  2. Существует ли приличный сервис облачных вычислений для Java, где я могу купить 5 миллионов секунд времени и запустить этот код за пять секунд?Что мне нужно сделать, чтобы подготовить мой код для работы в таком облаке?Сколько стоит 5 миллионов секунд?

Спасибо.

Ответы [ 6 ]

1 голос
/ 07 декабря 2010

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

Я также предполагаю, что существует корреляция между порядком списка проблем ипорядок списка решений - то есть solutions.get(3) - это решение для problems.get(3) - это было бы огромной проблемой для его распараллеливания.Было бы лучше иметь Pair<P, S> проблемы / решения, поэтому вам не нужно поддерживать корреляцию.

Распараллеливание метода решателя не составит труда, хотя от того, как вы это сделаете, зависитмного на вычислительных затратах каждого метода решения (как правило, чем дороже метод, тем ниже накладные расходы на распараллеливание, поэтому, если они очень дешевы, их нужно пакетировать).Если вы в конечном итоге получите распределенное решение, вы, конечно, будете иметь гораздо более высокие затраты.Платформа Executor и расширения fork / join будут отличной отправной точкой.

0 голосов
/ 06 декабря 2010

Ознакомьтесь с этой статьей о параллелизме:

По существу, новая модель Java 7 Fork / Join будет очень хорошо работать для этого подхода.По сути, вы можете настроить свои задачи на миллион с лишним, и они будут распределяться как можно лучше по всем доступным процессорам.Вы должны будете предоставить свой пользовательский исполнитель задачи «Облако», но это можно сделать.

Это, конечно, предполагает, что ваш алгоритм «решения» является параллельным параллельно.Короче говоря, до тех пор, пока Солвер полностью автономен, их можно разделить между произвольным числом процессоров.

0 голосов
/ 06 декабря 2010

Используйте соответствующего исполнителя. Посмотрите на http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool()

0 голосов
/ 06 декабря 2010
  1. Конечно, вы можете использовать стандартную парадигму рабочего потока для параллельного запуска вещей.Но будут некоторые накладные расходы на синхронизацию (например, обновление списка решений приведет к конфликту блокировок, когда все будет пытаться завершиться в одно и то же время), поэтому оно не будет запущено ровно через 5 секунд.Но это будет быстрее, чем 5 миллионов секунд: -)
  2. Amazon EC2 работает от 0,085 до 0,68 долл. США в час в зависимости от того, сколько ЦП вам нужно (см. стоимость ).Так что, может быть, около 120 долларов.Конечно, вам нужно настроить что-то отдельное, чтобы распределять свои задания по различным процессорам.Одним из вариантов может быть просто использовать Hadoop (см. Этот вопрос о том, является ли Hadoop подходящим для выполнения симуляций .

Вы можете прочитать такие вещи, как выступление Гая Стила о параллелизме для получения дополнительной информации о том, как мыслить параллельно.

0 голосов
/ 06 декабря 2010

Вы можете использовать одну программу для каждого входа, а затем использовать простой пакетный планировщик, такой как Condor (для Linux) или HPC (для Windows). Вы также можете запустить их на Amazon, но есть некоторая кривая обучения, это не просто «загрузить Java-код и перейти».

0 голосов
/ 06 декабря 2010

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

...