Mam kod, który pochłania dużą liczbę (obecnie miliony, a nawet miliardy) stosunkowo krótkich (5-100 elementów) tablic liczb losowych i wykonuje niektóre niezbyt intensywne zadania matematyczne im. Losowe liczby są, no cóż, przypadkowe, najlepiej chciałbym je wygenerować na wielu rdzeniach, ponieważ generowanie liczb losowych stanowi> 50% mojego środowiska wykonawczego w profilowaniu. Mam jednak trudności z rozprowadzaniem dużej liczby małych zadań w sposób, który nie jest wolniejszy od podejścia z pojedynczym gwintem.Wysokowydajne buforowanie strumienia potoków
Moje kodu aktualnie wygląda tak:
for(int i=0;i<1000000;i++){
for(RealVector d:data){
while(!converged){
double[] shortVec = new double[5];
for(int i=0;i<5;i++) shortVec[i]=rng.nextGaussian();
double[] longerVec = new double[50];
for(int i=0;i<50;i++) longerVec[i]=rng.nextGaussian();
/*Do some relatively fast math*/
}
}
}
Podejścia Wziąłem że mają nie pracował to:
- 1+ wątki Zapełnienie ArrayBlockingQueue, a moim głównym pętla spożywania i zapełnianie tablicy (boxing/unboxing był tu zabójcą)
- Generowanie wektorów z możliwością wywołania (przynoszącego przyszłość) podczas wykonywania niezależnych części matematyki (Wygląda na to, że nadwyżka nadwyżki przeważała nad każdym uzyskanym paralelizmem)
- Używanie 2 ArrayBlockingQueue, z których każdy jest wypełniony wątkiem, jeden dla krótkiego i jeden dla długich tablic (wciąż mniej więcej dwa razy wolniejszy niż bezpośredni jednowątkowy walizka).
Nie szukam "rozwiązań" dla mojego konkretnego problemu, tak jak radzić sobie z ogólnym przypadkiem generowania dużych strumieni małych, niezależnych prymitywów równolegle i konsumowania ich z jednego wątku.
@Gray too true. Zbliżenie się do odpowiedzi na pytanie. –
Dodano przykład użycia programu Exchanger do generowania losowych liczb w partiach w tle. –
Połączenie Exchanger do komunikacji i dzielenie dłuższych strumieni rodów bardzo pomogło. Dzięki. – Bryce