100% CPU usage reading from 115200 baud serial port
See original GitHub issueThis may be a general node.js issue, but I’m keen to learn the experts opinion on this. We are using nodejs on an Arduino YUN (MIPS 400 MHz). The serial port sends data at 115200 baud (fully saturated).
When I run a simple serial program to just receive the data from the serial port (and do nothing with it), it maxes out the CPU at 100% (about 70% user, 30% system according to top
):
'use strict';
var port = '/dev/ttyATH0';
var SerialPort = require("serialport").SerialPort;
var rs = new SerialPort(port, {
baudrate: 115200,
buffersize: 1024
});
rs.on('open', function () {
console.log('port opened!');
});
rs.on('data', function (data) {
// console.log(data);
});
The problem is, the program needs headroom to do a lot more than that and a simple ~14KB/s serial connection maxing out a 400Mhz CPU doesn’t seem entirely right to me.
Sure enough, a simple cat /dev/ttyATH0 > /dev/null
(note that this works on my system as the dev is configured for 115200 baud by default) results in around 15% CPU usage. cat /dev/ttyATH0 > /dev/ttyATH0
(piping RX to TX) works at around 5% (possibly due to saving kernel->user space copies).
So I dug deeper and tried to work with node.js fs
and a statically allocated buffer.
var fs = require('fs');
fs.open(port, 'r', function (err, fd) {
console.log('port opened! ' + err);
var buffer = new Buffer(8),
read;
function readCb(err, bytesRead, buffer) {
console.log(bytesRead);
process.nextTick(read); // continue reading
}
read = function () {
fs.read(fd, buffer, 0, buffer.length, null, readCb);
};
read();
});
Same results, 100% cpu according to top
.
Now, I’m totally surprised by this. Increasing the buffer sizes didn’t help in both cases either. Is there an inherent reason why Serialport/nodejs is so slow in just fetching the data from the serial port? Are there any performance tips you can offer? Or is the CPU usage reported by top just way off? (I believe this is not so, my investigations started because we were seeing massive lags in processing the serial data, to the tune of 10-20 seconds).
I assume @voodootikigod et. al. might have some insights to share from all those robot projects. Or is everyone using this on beefier hardware? (But still, doesn’t seem right to me to max out a 400Mhz CPU for a measly serial port).
Issue Analytics
- State:
- Created 9 years ago
- Comments:24 (15 by maintainers)
I’d say 100% CPU usage is to be expected in this case. When opening the serial port in serialport_unix.cpp the following code fragments are executed:
Because the timeout is 0 and the minimum number of characters to read is 1, characters are read and passed back to the following event listener from the first post above as quickly and as often as possible:
The baudrate is 115200, so the port is receiving about 11520 characters a second. This means that there will be a small number of characters available for passing back to the event listener on every turn of the event loop so CPU usage will be 100%.
5.0.0-Beta5
is now out with now even less code in the read and write paths. Hopefully it’s a little more stable for you.I’m going to close this issue due to it’s age, but if you’d like to continue with it feel free to comment and we’ll reopen.