Έχουν δημοσιευτεί
Σάββατο, 1 Σεπτεμβρίου 2007 11:52 πμ
από το μέλος
PALLADIN
Code hacking is fun... ειδικά όταν συνδυάζεις (functional + parallel) programming !!!
Η MS έχει ανακοινώσει ότι θα μας έχει Parallel LINQ... κάποια στιγμή... αλλα μέχρι τότε θα ήθελα τα LINQ queries μου να κρατούν busy το multi-core machine μου.
Οποτε αποφάσισα να δοκιμάσω μια "toy" υλοποίηση του Parallel LINQ...
(Είχα δοκιμάσει στο παρελθόν κάποιες απλές υλοποιησεις σε Scheme και Haskell,
αλλα τα Query Comprehensions του LINQ είναι αρκετά πιο clear σε όσους έχουν κάνει SQL coding)
Αποφάσισα να δοκιμάσω την υλοποίηση σε ένα ένα μηχανάκι που έχουμε στη δουλειά (τον φωνάζουμε zeus) με 4 cores (8 threads)
Πρώτα εκτελώ το sequential LINQ query (CPU Usage: 14%)
var items = from value in 1.To(n)
where value.IsPrime()
select new { Value = value, Binary = value.ToBinary() };

Και μετά την Parallel εκδοχή του (CPU Usage: 97%)
var items = from value in 1.To(n).ToParallel()
where value.IsPrime()
select new { Value = value, Binary = value.ToBinary() };

Όπως φαίνεται τα δυο queries είναι "σχεδόν" ίδια... εκτος από αυτό το περίεργο ToParallel() !!!
Για να έχουμε Parallel execution, το μονο που χρειάζεται είναι να καλέσουμε την ToParallel() extension method σε ένα IEnumerable<T> source.
Σε αυτο το release έχω υλοποιησει Parallel εκδόσεις των Select (also known as Map), Where (also known as Filter), και σκοπεύω να υλοποιήσω κάποια στιγμή μια Parallel Reduce method (για να ολοκληρώσω την κλασική τριάδα)
Μελλοντικά, θα εξετάσω πιθανά improvements, όπως την δυνατότητα για deferred execution, parameterized thread count... (ιδέες πολλές, αλλα πολύ λίγος ο ελεύθερος χρόνος)
Happy code hacking my friends
Διόρθωση (Βρήκα Bug):
Οι σωστές extension methods είναι:
public static bool IsPrime(this int number)
{
if(number < 2) return false;
int max = (int)Math.Sqrt(number);
return !(2.To(max).Any(value => number % value == 0));
}
public static IEnumerable<int> To(this int from, int to)
{
for(int i = from; i <= to; i++)
yield return i;
}