itm / wsn-device-drivers

Drivers for Wireless Sensor Network Devices
Other
6 stars 4 forks source link

Reduce number of threads per device #11

Closed danbim closed 13 years ago

danbim commented 13 years ago

Currently, each device driver instance uses 3 threads to do its work. There should be only the (necessary) RXTX thread and one (ideally shared) instance of some scheduler thread of a ScheduledExecutorService instance that is passed to the various classes which can be used to execute logic and handle user or device events.

psotres commented 13 years ago

¿Is there a critical performance issue if you have 2 or more threads per device? I'm currently thinking in how to support SmartSantander waspmote's requeriments in terms of operation concurrency (service together with experimentation at the same time on each device) with a minimun impact on the system performance.

Right know the best way that comes to my mind (in terms of threads) implies 2 threads per device, (plus one more for the RXTX but this is only one for all the attached devices in the gateway).

¿Do you think that this is going to have a great impact on the system?

If you think that having more than one thread per device can have a really negative impact on the whole system, maybe we can reduce to one per device, but not without loosing the posibility of having concurrency between "management operations" and not blocking the access to the device when waiting to the previous operation to finish (in a wireless multihop environment responses can have a delay of more than 20 seconds).

danbim commented 13 years ago

Generally speaking the number of threads allone doesn't say much about how the performance will be as most threads could be sleeping most of the time (as it is the case right now). To reach a high level of concurrency you actually don't need a fixed number of threads, say, per device, but more a clever logic on how to transport data and do work. There's a "pattern" that takes chunks of work (= a job) (e.g. data received from the UART) and processes it using a thread out of a thread pool. As soon as this job is done the thread can return to idle in the threadpool. Event driven frameworks usually build upon this logic. So does, e.g. JBoss Netty, scaling to about 50k connections concurrently on a commodity hardware "server".

I want to use the same principle for the driver implementation as it is really easy and straightforward to implement. Basically RXTX would have one thread to read and write to the UART (there's no way around it) and for everything else we would apply the "piece of work is done by an arbitrary worker thread from the pool"-pattern.

danbim commented 13 years ago

What we win by having less threads I guess is ressource efficiency in terms of memory usage and potentially less thread synchronisation points if done right. However, the latter is not so important as I think the load that the serial connection can provide is pretty low compared to what even cheap embedded hardware can handle. Anyways, the lower the ressource demands, the better.

psotres commented 13 years ago

I don't really understand the whole concept, but it sounds great. Anyway, in our current multiplexed driver we only need one RXTX thread for handling all devices connected with the GW.

danbim commented 13 years ago

Sure, in your case that makes sense because there's only one thread per device. It's always one thread per RXTX connection.

mlegenhausen commented 13 years ago

Idea:

Submit always one operation at the time to the ExecutorService. Then add a Runnable to the ListenableFuture use for this the same ExecutorService. In the Runnable submit the next Operation to the ExecutorService. Should be easy ;)

The same ExecutorService can be used for the TimeLimiter. See Issue #42. When doing this you need to make sure that you can have min n+1 threads in your Pool. The +1 Thread is needed by the TimeLimiter. The n Threads are needed when each Device is executing an Operation. These threads do not need to exists the whole time. In best case your application can run with only 2 threads. This calculation does not include the RXTX threads.

mlegenhausen commented 13 years ago

Cause of the mechanism that is used now, there is not anymore the possibility to reduce the thread amout in such a massiv way. We need always one thread that reads from the inputstream when no operation is running. This can be optimized by creating something like a idle operation that is submitted to the queue when no operation is running. When a new operation is submitted the idle operation is canceled.

mlegenhausen commented 13 years ago

Implementation notes: The Idle Operation management should be added to the OperationQueue. To prevent dependencies to the Connection, a setter for the Idle Operation should be added.

mlegenhausen commented 13 years ago

The OperationQueue should work with any kind of ExecutorService, not only the SingleThreadExecutor. This would allow to use one ExecutorService for the whole Device.

mlegenhausen commented 13 years ago

The amount of threads is now reduced to 3 * n + 1 Threads, where n is the amount of devices. The 3 threads are RXTX, the OperationQueue and the TimeLimiter that limits the execution time of an operation. The last thread is needed for the outputstreams to flush them automatically every 50ms. The Copy thread is now a idle thread that runs in the OperationQueue.

danbim commented 13 years ago

What's the state of this issue? Do you think we can close it?

mlegenhausen commented 13 years ago

This issue is feature complete and can be closed.