Mam zadanie intensywne procesora (zapętlając niektóre dane i wyniki oceny). Chcę korzystać z wielu rdzeni, ale moja wydajność jest zdecydowanie gorsza niż użycie pojedynczego rdzenia.nodejs - znajduję wielowątkowość lub używanie wielu procesów jest wolniejsze niż jeden proces. Czemu?
Próbowałem:
- Tworzenie wielu procesów na różnych portach z express i wysyłanie zadań do tych procesów
- Korzystanie webworker-threads do uruchamiania zadań w różnych wątków przy użyciu puli wątków
Zmierzam wyniki, licząc całkowitą liczbę powtórzeń, które mogę wykonać i dzieląc przez czas, jaki spędziłem na pracy nad problemem. Podczas korzystania z jednego rdzenia moje wyniki są znacznie lepsze.
niektóre interesujące:
- mogę określić, kiedy jestem tylko przy użyciu jednego rdzenia i kiedy używam wielu rdzeni poprzez Menedżer zadań. Używam spodziewanej liczby rdzeni.
- mam dużo pamięci RAM
- Próbowałem uruchomione na zaledwie 2 lub 3 rdzenie
- I dodał nextTicks który nie wydaje się wpływać na cokolwiek w tym przypadku
- Zadania potrwać kilka sekund każdy tak ja nie czuję, że tracę dużo na głowie
Czy masz pojęcie, co się tutaj dzieje?
Aktualizacja dla wątków: Podejrzewam błąd w WebWorker gwinty Pomijanie express do teraz, myślę, że problem może mieć do czynienia z moim pętli nici. Co robię, to tworzenie wątków, a następnie próba ich nieprzerwanego uruchamiania, ale wysyłanie danych między nimi. Mimo że oba wątki zużywają procesor, tylko wątek 0 zwraca wartości. Moje założenie było takie, że generalnie skończyłoby się emitowaniem wiadomości do wątku, który był bezczynny najdłużej, ale nie wydaje się, żeby tak było. Mój zestaw górę wygląda to
ciągu threadtask.js
thread.on('init', function() {
thread.emit('ready');
thread.on('start', function(data) {
console.log("THREAD " + thread.id + ": execute task");
//...
console.log("THREAD " + thread.id + ": emit result");
thread.emit('result', otherData));
});
});
main.js
var tp = Threads.createPool(NUM_THREADS);
tp.load(threadtaskjsFilePath);
var readyCount = 0;
tp.on('ready', function() {
readyCount++;
if(readyCount == tp.totalThreads()) {
console.log('MAIN: Sending first start event');
tp.all.emit('start', JSON.stringify(data));
}
});
tp.on('result', function(eresult) {
var result = JSON.parse(eresult);
console.log('MAIN: result from thread ' + result.threadId);
//...
console.log('MAIN: emit start' + result.threadId);
tp.any.emit('start' + result.threadId, data);
});
tp.all.emit("init", JSON.stringify(data2));
Wyjście do tej katastrofy
MAIN: Sending first start event
THREAD 0: execute task
THREAD 1: execute task
THREAD 1: emit result
MAIN: result from thread 1
THREAD 0: emit result
THREAD 0: execute task
THREAD 0: emit result
MAIN: result from thread 0
MAIN: result from thread 0
THREAD 0: execute task
THREAD 0: emit result
THREAD 0: execute task
THREAD 0: emit result
MAIN: result from thread 0
MAIN: result from thread 0
THREAD 0: execute task
THREAD 0: emit result
THREAD 0: execute task
THREAD 0: emit result
MAIN: result from thread 0
MAIN: result from thread 0
próbowałam inne podejście gdzie wyślę wszystkie, ale potem każdy wątek będzie słuchał wiadomości, na którą tylko ona może odpowiedzieć. Np. Thread.on ('start' + thread.id, function() {...}). To nie działa, ponieważ w wyniku, kiedy robię tp.all.emit ("start" + result.threadId, ...), wiadomość nie zostanie odebrana.
MAIN: Sending first start event
THREAD 0: execute task
THREAD 1: execute task
THREAD 1: emit result
THREAD 0: emit result
Po tym wszystkim nic więcej się nie dzieje.
Aktualizacja dla wielu serwerów ekspresowych: Dostaję ulepszeń ale mniejszy niż oczekiwano
I revisited tego rozwiązania i miał więcej szczęścia. Myślę, że mój oryginalny pomiar mógł być wadliwy. Nowe wyniki:
- jednego procesu: 3.3 iteracje/sekundę
- głównego procesu + 2 serwery: 4.2 iteracje/sekundę
- głównego procesu + 3 serwery: 4.9 iteracje/sekundę
jedna rzecz Trochę dziwne, że nie widzę około 6 iteracji/sekundę dla 2 serwerów i 9 dla 3. Dostaję, że są pewne straty dla sieci, ale jeśli zwiększę mój czas pracy, aby być wystarczająco wysoki, straty sieci powinny bądźmy drobni, tak bym pomyślał.
Czy jesteś pewien, że jesteś powiązany z procesorem i nie jesteś związany? –
Dość pewne. Czy wiesz, w jaki sposób mogę potwierdzić, że nie jest on związany? Nie ładuję niczego z dysku po zainicjowaniu wątków. Przesyłam kilka tablic jsonów do wątków, ale nie są one ogromne. – i8abug
Miej oko na wykorzystanie dysku/sieci i sprawdź, czy wygląda na wyczerpującą. –