Próbuję użyć przetwarzania równoległego, aby przyspieszyć kilka zagnieżdżonych pętli, ale mam problemy z uzyskaniem prawidłowej składni. Próbuję uzyskać liczbę pikseli w bitmapie: czerwoną, białą lub czarną, wartości, które mam w wyliczeniu gdzie indziej.Równoległa dla pętli w C# ze wspólną zmienną
W przetwarzania szeregowego Mam następujący kod, który działa prawidłowo:
Bitmap image = new Bitmap(@"Input.png");
var colourCount = new int[3];
for (var x = 0; x < image.Width; x++)
{
for (var y = 0; y < image.Height; y++)
{
switch (image.GetPixel(x, y).ToArgb())
{
case (int)colours.red: colourCount[0]++; break;
case (int)colours.white: colourCount[1]++; break;
case (int)colours.black: colourCount[2]++; break;
default: throw new ArgumentOutOfRangeException(string.Format("Unexpected colour found: '{0}'", image.GetPixel(x, y).ToArgb()));
}
}
}
Widziałem kod równolegle do pętli przez Microsoft i od Stackoverflow że zaktualizować zmienną udostępnionego takie jak poniżej:
Parallel.For<int>(0, result.Count,() => 0, (i, loop, subtotal) =>
{
subtotal += result[i];
return subtotal;
},
(x) => Interlocked.Add(ref sum, x)
);
Ale wszystkie przykłady używają prostego typu, takiego jak int jako zmienna dzielona i po prostu nie mogę znaleźć składni, aby napisać do mojej tablicy wielkości 3. Czy podchodzę do tego źle?
Nawiasem mówiąc, wiem pod względem wydajności, że GetPixel jest bardzo powolny w porównaniu do czegoś w rodzaju Bitmap.LockBits, po prostu próbuję uzyskać zasadę równoległych pętli w prawo.
Właściwie nie potrzebujesz 'blokady' w' localFinally'. Zamiast tego możesz użyć 'Interlocked.Add()' w swojej pętli. Chociaż użycie 'lock' sprawia, że jest to bardziej poprawne. – svick
@svick: Wiele inwokacji 'Interlocked.Add' może być mniej wydajne niż pojedynczy' lock'. (Zdecydowanie miałoby to miejsce, gdyby "colourCount" składało się z kilkudziesięciu elementów, nie na pewno dla 3.) Per [Albahari] (http://www.albahari.com/threading/part4.aspx): "All of" Interlocked "Metody metody generują pełne ogrodzenie". Powtarzające się obciążenie związane z unieważnieniem pamięci podręcznej może przekraczać koszt pojedynczej blokady. – Douglas
Dzięki za opublikowanie tego, teraz ma dla mnie dużo więcej sensu. Masz rację sugerując, że GetPixel nie jest bezpieczny dla wątków, w rzeczywistości dostęp do dowolnej właściwości obrazu lub metod wydaje się być nie-nie, więc muszę wymyślić na odwrót, ale mam ale sama pętla działa dobrze. Dzięki jeszcze raz! –