I have a task with heavy CPU usage (cyclic processing of some data and evaluating the results). I want to use several cores for them, but my performance is consistently worse than just using one core.
I tried:
- Creation of several processes on different ports with express and sending tasks to these processes
- Using webworker-threads to run tasks on different threads using a thread pool
I measure the results by counting the total number of iterations I can perform and divide by the amount of time I spent on this problem. When using a single core, my results are much better.
some interesting points:
- I can determine when I just use one core, and when I use multiple cores through the task manager. I use the expected number of cores.
- I have a lot of ram
- I tried to work only on 2 or 3 kernels.
- I added nextTicks, which does not seem to affect anything in this case
- Tasks take a few seconds, so I don't feel like losing a lot of overhead
Any idea what is going on here?
Update for threads: I suspect an error in webworker-threads Skipping express at the moment, I think the problem may be related to my thread loop. What I'm doing is creating threads, and then trying to constantly run them, but send data back and forth between them. Although both threads use a processor, only thread 0 returns values. My assumption was that any one of them, as a rule, ultimately emitted a message into a stream that was idle for longer, but this does not seem to be the case. My setup looks like this:
Inside threadtask.js
thread.on('init', function() { thread.emit('ready'); thread.on('start', function(data) { console.log("THREAD " + thread.id + ": execute task");
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);
Result of this disaster
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
I tried another approach, where I would choose everything, but then each thread listened to a message to which it could respond. For example, thread.on ('start' + thread.id, function () {...}). This does not work, because as a result, when I do tp.all.emit ('start' + result.threadId, ...), the message does not receive.
MAIN: Sending first start event THREAD 0: execute task THREAD 1: execute task THREAD 1: emit result THREAD 0: emit result
After that, nothing happens.
Update for multiple express servers: I get improvements, but less than expected
I reviewed this decision and had more luck. I think my initial measurement may have been erroneous. New Results:
- Single process: 3.3 iterations / sec
- Main process + 2 servers: 4.2 iterations / sec
- The main process + 3 servers: 4.9 iterations / sec
One thing that I find a little strange is that I do not see about 6 iterations per second for 2 servers and 9 for 3. I understand that there are some losses for working on the network, but if I increase the time of my task, to be high enough, network losses should be pretty small, I would think.