Witam.
Chciałem wykonać test wydajności kilku elementów mojego programu.
Sytuacja wygląda tak:
- Mamy tablicę zawierającą liczby typu int. Tablica zawiera 150000000 elementów.
- Tablicę przeglądamy 30 razy pod rząd. (jest to przykład testowy i nie ma biznesowego sensu. Chodzi o sprawdzenie wydajności.)
- Podczas pobierania danych z tablicy wykonujemy na nich proste operacje matematyczne. Wzór przykładowej operacji:
Math.Truncate((double)(factor * (a[i] - 128) + 128));
gdzie "factor" ma wartość: 2.96952552013 i jest typu double.
a[i] to oczywiście element naszej wielkiej tablicy pobierany sekwencyjnie w pętli.
Na moim procesorze wyniki wyglądają tak:
128 watkow : 146.296090 sekund
8 watkow : 67.5066023 sekund
4 wątki : 71.3351512 sekund
1 watek : 56.9286375 sekund
Bez wątków : 56.9447681 sekund
Jak widać najlepsza wydajność była bez wątków. Bardzo mnie to zaskoczyło. Wątki wykorzystane z tych testach to zwykłe Thread.
Poniżej wykonałem analogiczny test dla wątków typu Task.
128 wątków taska : 74.7024587
1 wątek taska : 57.1611088 sekund
4 wątki taska : 68.196011 sekund
8 wątków taska : 67.284446199999991 sekund
Tutaj sytuacja wygląda podobnie.
W związku z tym mam pytanie.
Dlaczego użycie wątków spowolniło operacje na tablicy?
Spodziewałem się raczej, że wątki (szczególnie 8, gdyż mam 8 rdzeni) spowodują najwyższą wydajność.
Kod:
private static int[] a = new int[150000000];
private static int factor = 2.96952552013;
private static double value = 0;
private static int iloscWatkow = 8;
private static void Test()
{
TimeSpan globalTime = TimeSpan.Zero;
Task[] threads = new Task[iloscWatkow];
for (int i = 0; i < 30; i++)
{
Stopwatch watch = new Stopwatch();
watch.Start();
for (int t = 0; t < iloscWatkow; t++)
{
threads[t] = new Task(delegate { ThreadMethod(t); });
threads[t].Start();
}
do
{
} while (threads.Any(x => x.IsCompleted == false));
watch.Stop();
globalTime = globalTime.Add(watch.Elapsed);
}
}
private static void ThreadMethod(int start)
{
for (int i = start; i < a.Length; i += iloscWatkow)
{
value = Math.Truncate((double)(factor * (a[i] - 128) + 128));
}
}
Jak widzicie wątki nie operują wewnątrz pętli wykonującej kolejne operacje.
Działają na zasadzie: każdy wątek ma swoją pulę danych w tablicy do przeanalizowania. Stąd parametr Start i skoki w pętlach.
Czy może mi ktoś wyjaśnić dlaczego wątki działają dłużej niż brak wątków lub jeden wątek?
Pozdrawiam.