Niedawno odpowiedziałem na pytanie dotyczące optymalizacji prawdopodobnej, równoległej metody generowania każdej permutacji dowolnych numerów bazowych. Zamieściłem odpowiedź podobną do tej, słaba realizacja listy zablokowanych kod parallelized, a ktoś prawie natychmiast zwróciłem na to uwagę:Parallel Framework i unikanie fałszywego współdzielenia
To jest dość dużo gwarancją daje fałszywy podział i będzie prawdopodobnie wiele razy wolniej. (Kredyt do gjvdkamp)
i mieli rację, to było śmierć powolny. Powiedział, że badałem temat i znalazłem jakieś interesting material and suggestions do walki z nim. Jeśli rozumiem to poprawnie, gdy wątki uzyskują dostęp do sąsiedniej pamięci (na przykład do tablicy, która prawdopodobnie jest zgodna z ConcurrentStack
), prawdopodobne jest fałszywe udostępnianie.
dla kodu poniżej linii poziomej, o Bytes
jest:
struct Bytes {
public byte A; public byte B; public byte C; public byte D;
public byte E; public byte F; public byte G; public byte H;
}
Dla własnego testów, chciałem dostać równoległą wersję tego biegania i być prawdziwie szybciej, więc stworzyłem prosty przykład oparty na oryginalnym kodzie. 6
jako limits[0]
był leniwy wybór z mojej strony - mój komputer ma 6 rdzeni.
pojedynczy wątek blokŚredni czas pracy: 10s0059ms
var data = new List<Bytes>();
var limits = new byte[] { 6, 16, 16, 16, 32, 8, 8, 8 };
for (byte a = 0; a < limits[0]; a++)
for (byte b = 0; b < limits[1]; b++)
for (byte c = 0; c < limits[2]; c++)
for (byte d = 0; d < limits[3]; d++)
for (byte e = 0; e < limits[4]; e++)
for (byte f = 0; f < limits[5]; f++)
for (byte g = 0; g < limits[6]; g++)
for (byte h = 0; h < limits[7]; h++)
data.Add(new Bytes {
A = a, B = b, C = c, D = d,
E = e, F = f, G = g, H = h
});
parallelized, biedny realizacjiRun Time AVG: 81s729ms, ~ 8700 twierdzenia
var data = new ConcurrentStack<Bytes>();
var limits = new byte[] { 6, 16, 16, 16, 32, 8, 8, 8 };
Parallel.For(0, limits[0], (a) => {
for (byte b = 0; b < limits[1]; b++)
for (byte c = 0; c < limits[2]; c++)
for (byte d = 0; d < limits[3]; d++)
for (byte e = 0; e < limits[4]; e++)
for (byte f = 0; f < limits[5]; f++)
for (byte g = 0; g < limits[6]; g++)
for (byte h = 0; h < limits[7]; h++)
data.Push(new Bytes {
A = (byte)a,B = b,C = c,D = d,
E = e,F = f,G = g,H = h
});
});
parallelized, ?? RealizacjaRun czas avg: 5s833ms, 92 twierdzenia
var data = new ConcurrentStack<List<Bytes>>();
var limits = new byte[] { 6, 16, 16, 16, 32, 8, 8, 8 };
Parallel.For (0, limits[0],() => new List<Bytes>(),
(a, loop, localList) => {
for (byte b = 0; b < limits[1]; b++)
for (byte c = 0; c < limits[2]; c++)
for (byte d = 0; d < limits[3]; d++)
for (byte e = 0; e < limits[4]; e++)
for (byte f = 0; f < limits[5]; f++)
for (byte g = 0; g < limits[6]; g++)
for (byte h = 0; h < limits[7]; h++)
localList.Add(new Bytes {
A = (byte)a, B = b, C = c, D = d,
E = e, F = f, G = g, H = h
});
return localList;
}, x => {
data.Push(x);
});
Jestem zadowolony, że dostał implementację, która jest szybsza niż jedną wersję gwintowany. Oczekiwałem wyniku bliższego około 10 s/6, czyli około 1,6 s, ale to prawdopodobnie naiwne oczekiwanie.
Moje pytanie brzmi: dla równoległej implementacji, która jest rzeczywiście szybsza od wersji jednowątkowej, czy istnieją dodatkowe optymalizacje, które można zastosować do operacji? Zastanawiam się nad optymalizacją związaną z równoległością, a nie ulepszeniami algorytmu używanego do obliczania wartości. Konkretnie:
- wiem o optymalizacji przechowywania i zaludniać jako
struct
zamiastbyte[]
, ale nie jest to związane z parallelization (lub nie?) - wiem, że pożądana wartość może być leniwy oceniana z dodatek sumujący, ale taki sam jak optymalizacja
struct
.
Czy jesteś lepiej opublikowania tego programistów w [] (http://programmers.stackexchange.com/)? Lepiej jednak zrobić 1 a Golf [wyzwanie] (http://codegolf.stackexchange.com/) – lloyd
@lloydm jaki jest problem z tym pytaniem w stackoverflow? To świetnie, że jest tu przynajmniej kilka interesujących, trudnych pytań, a nie tylko milion komunikatów o błędach lub problemów z składnią. – Prokurors
@Prokurory Nie ma wątpliwości, że to interesujące i wymagające. Dowiedziałem się o fałszywym udostępnianiu. Po ponownym przeczytaniu poprawnych pytań zgadzam się, że zaznacza pola jako prawidłowe pytanie. – lloyd