uml-robotics / ROS.NET

ROS.NET: ROS Client Library for Windows Development in C#
BSD 2-Clause "Simplified" License
93 stars 52 forks source link

Cpu Usage #27

Closed synologic closed 8 years ago

synologic commented 8 years ago

Hello,

i am experiencing a very high CPU usage with your library, even when it's doing nothing.

I connect to ROS and without any subscription, it uses 100% of a CPU core.

Profiling shows that a lot of CPU is spent in CallbackQueue:threadFunc.

Any insights on this ?

nuclearmistake commented 8 years ago

Does it actually connect to the master? or is it failing to?

Otherwise, I'd have to see your code... I'm currently looking for a bottleneck that is throttling /tf subscription at 500hz inside a unity game... and that game is only using 30% CPU

nuclearmistake commented 8 years ago

need more info about the system you're running in... where master is, what your and its environment variables look like, etc.

synologic commented 8 years ago

Yes, it connects to the master just fine. What I am trying to obtain, is the occupancy grid from SLAM.

I am running ROS in a VM (2 cores, which are enough for the SLAM), and the application on the same machine (i7 4770k / 32g ram)

If I just have roscore running with no other nodes, and I connect this node to roscore, subscribing to a topic that is not published by any other node, the CPU usage is at a steady 25% (basically a full core used).

When the topic gets published, and the occupancy grid is being published, I see some spikes of about 7-10% which is probably normal due to the fact that data is coming from ROS.

The code is based on your listener example, I just set the master URI and my hostname.

I can post code later today if needed.

nuclearmistake commented 8 years ago

Are you using ip addresses or hostnames for ROS_MASTER_URI and ROS_HOSTNAME? I usually explicitly set each machine's ROS_HOSTNAME to be its IP and use http://[master ip]:11311 for the uri... given the TCP socket lifecycle, it's unlikely that it's DNS, but mUncrontrolledVariables--

How heavy is the work you're doing in the occupancy grid callback? Maybe a lazy producer+consumer pattern with a work thread operating on a queue (or just the last one) of received grids would alleviate "constructive interference" between the heavy callback function and the clunky callback+message-handling code calling it?

synologic commented 8 years ago

Yes, always IP addresses, as the app is on windows and ros on linux, and they are not using a common name server ... obviously we just skip a DNS lookup by using IPs.

The slam is set to update the map every 2 seconds, so the callback gets fired every 2 and some seconds (accounting for the data transfer).

The grid itself is not that big, but not that small either, is usually 2048x2048 cells.

Normally, this won't matter too much, however I intend to run the subscriber app I'm building on a Surface tablet which has only an atom cpu :)

I have a consumer/producer pattern already in place that queues the grids, even tho the consumer is much faster than the producer, so the size of the queue is 1 or 0 most of the times.

The problem is the cpu time spent while nothing is happening.

nuclearmistake commented 8 years ago

hmm... I have a netbook with an atom N570... will try to replicate.

Assuming you don't have access to a visual studio edition with a profiler, would you be able to take a peek at your code running with a trial of JetBrains dotTrace (or equivalent)?

synologic commented 8 years ago

Ok so, here's the code i'm using

ROS.ROS_MASTER_URI = "http://192.168.34.39:11311"; ROS.Init(args, "Listener"); NodeHandle node = new NodeHandle(); ROS.waitForShutdown();

no other subscriptions or anything.

VS2015 Community's profiler shows: image

And the output of dotTrace: image

EDIT: Addint Thread.sleep(1) just before if (!callAvailable(ROS.WallDuration)) in threadFunc, helps a lot. Not sure about the impact (yet).

So it looks like callAvailable executes way too fast :)

nuclearmistake commented 8 years ago

That's 97% of the 15-20% process CPU usage. Not 97% of the CPU. The bottom bar graph is more representative of the CPU being used by the whole program. On Jun 6, 2016 5:22 AM, "synologic" notifications@github.com wrote:

Ok so, here's the code i'm using

ROS.ROS_MASTER_URI = "http://192.168.34.39:11311"; ROS.Init(args, "Listener"); NodeHandle node = new NodeHandle(); ROS.waitForShutdown();

no other subscriptions or anything.

VS2015 Community's profiler shows: [image: image] https://cloud.githubusercontent.com/assets/10828699/15817572/e4aa9698-2bd8-11e6-91a6-c79999d2660b.png

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/uml-robotics/ROS.NET/issues/27#issuecomment-223908751, or mute the thread https://github.com/notifications/unsubscribe/ABLrW6FuDgI8yjSDq_w_8PqjRK-spTvAks5qI-bFgaJpZM4IpUe8 .

synologic commented 8 years ago

As i said, 20% CPU usage on my i7 is pretty much a whole core out of 4, so it's still a lot while doing nothing.

nuclearmistake commented 8 years ago

Aye... I'm working on revising the socket polling mechanism ATM. The callback queue code is somewhere between strict translation from C++ and C# reimplementation, and is clunky and scales weird. You're welcome to poke around :-P On Jun 6, 2016 10:06 AM, "synologic" notifications@github.com wrote:

As i said, 20% CPU usage on my i7 is pretty much a whole core out of 4, so it's still a lot while doing nothing.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/uml-robotics/ROS.NET/issues/27#issuecomment-223969064, or mute the thread https://github.com/notifications/unsubscribe/ABLrW6ixOuP42SdgjtMhDYhKKefoHKG-ks5qJClNgaJpZM4IpUe8 .

synologic commented 8 years ago

Will do, however seeing this is my first ever C# project ... :) But, as I previously said, by adding Thread.sleep(1) in the threadFunc pretty much reduced the CPU usage to 0%

nuclearmistake commented 8 years ago

sorted out on the current master?

synologic wrote:

Will do, however seeing this is my first ever C# project ... :) But, as I previously said, by adding Thread.sleep(1) in the threadFunc pretty much reduced the CPU usage to 0%

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/uml-robotics/ROS.NET/issues/27#issuecomment-223985673,

or mute the thread https://github.com/notifications/unsubscribe/ABLrWwRZXcBQxKJ1YxDQ2TcsE4UjFYVKks5qJDYigaJpZM4IpUe8.

synologic commented 8 years ago

Yes