Hi Jürg,
Thanks a lot for your quick response.
As your recommend, I've change my vala server to have only two timeout
sources (see attached code) but results are similar (about 13.3% CPU
used on my machine)
I don't think the problem is on the thread manipulation, timeouts, and
probably not even in Vala. I think the problem is on the D-Bus
implementation (maybe on glib?). In my attached code:
- If you set SEND_SIGNALS = true --> 13.3%CPU used
- If you set SEND_SIGNALS = false --> 0% CPU used
Regards,
Borja
El 04/06/12 14:34, Jürg Billeter escribió:
Hi Borja,
On Mon, 2012-06-04 at 13:58 +0200, Borja Rodríguez Diliz wrote:
I want to use Vala and Dbus for a project in which I need to exchange
information between objects about 4 Hz . The final target is to run the
software on an embedded device (with a limited CPU / RAM)
I performed some tests and I noticed that using Vala instead of plain C
requires significantly more CPU requirements.
The test:
- A dbus server with 200 objects registered. Each object sends the
following signals:
signalA: a double value with a frequency of 4 Hz
signalB: a double value every 2 seconds
- A client subscribed to 'signalA'
- A client subscribed to 'signalB'
You use quite different approaches in the Vala version and the plain C
version. In the plain C server you start 400 threads (1 per object and
signal) and let them run/sleep in parallel. In the Vala server you use a
single application thread with an event loop and 400 timeout sources.
I'm not surprised that the two approaches have different performance
characteristics, however, that's not related to the chosen programming
language. It's possible that you hit the scalability of GMainLoop, but
I'm not sure whether that's where the overhead comes from.
You could easily create 400 threads in Vala and you would probably get
similar CPU usage in the Vala and C version. However, I'm not convinced
that creating 400 (+ another 400 in the clients) mostly sleeping threads
is the best approach given that the target has limited CPU/RAM.
Something you could try is to have only two timeout sources (one per
signal frequency) and use a loop in the timeout handler to send all
signals.
Regards,
Jürg
// Nbr of object to register
int numberObjects=200;
DemoServer []myServers;
bool SEND_SIGNALS=true;
[DBus (name = "net.prx.test")]
public class DemoServer : Object {
private int counterA;
private int counterB;
public void sendSignalA(){
if (SEND_SIGNALS){
newSignalA(counterA);
}
counterA++;
}
public void sendSignalB(){
if (SEND_SIGNALS){
newSignalB(counterB);
}
counterB++;
}
public signal void newSignalA (double value);
public signal void newSignalB (double value);
}
[DBus (name = "net.prx.test")]
public errordomain DemoError
{
SOME_ERROR
}
void on_bus_aquired (DBusConnection conn) {
stdout.printf ("Bus adquired\n");
myServers=new DemoServer[numberObjects];
for (int i=0;i<numberObjects;i++){
try {
myServers[i]=new DemoServer ();
conn.register_object ("/net/prx/test/"+i.to_string(), myServers[i]);
} catch (IOError e) {
stderr.printf ("Could not register service\n");
}
}
Timeout.add (250, () => {
for (int i=0;i<numberObjects;i++){
myServers[i].sendSignalA();
}
return true;
});
Timeout.add (2000, () => {
for (int i=0;i<numberObjects;i++){
myServers[i].sendSignalB();
}
return true;
});
}
void on_name_adquired (DBusConnection conn) {
stdout.printf("Name adquired");
}
void on_name_lost (DBusConnection conn) {
stdout.printf("Name lost");
}
void main () {
Bus.own_name (BusType.SYSTEM, "net.prx.genio.prx", BusNameOwnerFlags.NONE,
on_bus_aquired,
on_name_adquired,
on_name_lost);
new MainLoop ().run ();
}
_______________________________________________
vala-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/vala-list