Лучшая многопоточность: отдельные функции или функции сбора - PullRequest
0 голосов
/ 13 июня 2009

Я не знаю, правильно ли я сформулировал это, но для простого примера, скажем, у нас есть набор значений Point3 (скажем, 1M).

У нас есть метод Offset, который добавляет к этим значениям еще одно значение Point3, возвращая новые значения Point3. Допустим, метод является статическим.

Тип Point3 является неизменным.

Вопрос в том, должен ли я иметь такой метод:

public static Point3 Offset ( Point3 a, Point3 b )

или

public static IEnumerable<Point3> Offset ( IEnumerable<Point3> a, IEnumerable<Point3> b )

Мне # 1 кажется лучшим выбором разбить задачу на отдельные задачи для разных потоков.

Что ты думаешь? А преимущества перед № 1 или № 2?

Ответы [ 4 ]

2 голосов
/ 13 июня 2009

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

2 голосов
/ 13 июня 2009

Вероятно, у вас должно быть первое, а во втором вызове первый.

1 голос
/ 14 июня 2009

Вариант 1 - логическая операция ядра. В .NET 4.0 вы можете выполнить ту же операцию, что и в варианте 2, используя оператор Zip. Из памяти вместо:

var newPoints = Offset(firstPoints, secondPoints);

вы бы написали:

var newPoints = firstPoints.Zip(secondPoints, (p1, p2) => Offset(p1, p2));

Возможно, вы захотите сделать Offset методом расширения для Point3, если вы также используете .NET 3.5. (В качестве альтернативы, если вы управляете типом Point3, это звучит как логическое дополнение - было бы неплохо написать (p1, p2) => p1 + p2 в вызове Zip.

Если вы не используете .NET 4.0, но вам нравится Zip, у нас есть реализация в MoreLINQ - это довольно просто.

Пока что ничего не было связано с многопоточностью ... сейчас я не знаю, есть ли реализация PLINQ Zip в .NET 4.0, но было бы целесообразно, чтобы она была, IMO .

1 голос
/ 13 июня 2009

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

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

...