Interfejs API Stream został zaprojektowany tak, aby ułatwić pisanie obliczeń w sposób oderwany od sposobu ich wykonywania, ułatwiając przełączanie między sekwencyjnym a równoległym.
Jednak tylko dlatego, że jest łatwy, nie oznacza, że zawsze jest to dobry pomysł, a tak naprawdę, to zły pomysł, aby po prostu rzucić się .parallel()
w to miejsce tylko dlatego, że możesz.
Po pierwsze, zauważ, że równoległość nie oferuje żadnych innych korzyści poza możliwością szybszego wykonania, gdy dostępnych jest więcej rdzeni. Wykonanie równoległe zawsze będzie wymagało więcej pracy niż wykonanie sekwencyjne, ponieważ oprócz rozwiązania problemu musi również wykonywać wysyłanie i koordynację pod-zadań. Mamy nadzieję, że szybciej uzyskasz odpowiedź, dzieląc pracę na wiele procesorów; to, czy tak się faktycznie dzieje, zależy od wielu rzeczy, w tym od wielkości zbioru danych, ilości obliczeń wykonywanych dla każdego elementu, charakteru obliczeń (w szczególności, czy przetwarzanie jednego elementu współdziała z przetwarzaniem innych?) , liczbę dostępnych procesorów i liczbę innych zadań konkurujących o te procesory.
Ponadto zauważ, że równoległość często ujawnia również niedeterminizm w obliczeniach, który często jest ukryty przez sekwencyjne implementacje; czasami nie ma to znaczenia lub można je złagodzić ograniczając związane z tym operacje (tj. operatory redukcji muszą być bezpaństwowcami i asocjatywne).
W rzeczywistości czasami paralelizm przyspieszy obliczenia, czasem nie, a czasem nawet spowolni. Najlepiej jest najpierw opracować przy użyciu wykonywania sekwencyjnego, a następnie zastosować równoległość gdzie
(A) wiesz, że tak naprawdę korzyści płyną ze zwiększonej wydajności i
(B) że faktycznie zapewni zwiększoną wydajność.
(A) to problem biznesowy, a nie techniczny. Jeśli jesteś ekspertem od wydajności, zwykle będziesz w stanie spojrzeć na kod i ustalić (B), ale inteligentną ścieżką jest pomiar. (I nawet nie zawracaj sobie głowy, dopóki nie przekonasz się o (A); jeśli kod jest wystarczająco szybki, lepiej zastosować cykle mózgowe w innym miejscu).
Najprostszym modelem wydajności dla równoległości jest model „NQ”, w którym N oznacza liczbę elementów, a Q jest obliczeniem na element. Ogólnie rzecz biorąc, potrzebujesz NQ produktu, aby przekroczyć pewien próg, zanim zaczniesz uzyskiwać korzyści z wydajności. W przypadku problemu o niskiej wartości Q, takiego jak „zsumowanie liczb od 1 do N”, generalnie widać wartość progową między N = 1000 a N = 10000. W przypadku problemów z wyższym Q zobaczysz progi rentowności przy niższych progach.
Ale rzeczywistość jest dość skomplikowana. Tak więc, dopóki nie osiągniesz stanu eksperymentalnego, najpierw określ, kiedy sekwencyjne przetwarzanie faktycznie cię kosztuje, a następnie zmierz, czy równoległość pomoże.