GNOME Accessibility Logo

GNOME Accessibility Team

/!\ The following content is being kept here for historical preservation only. The information contained herein may or may not be accurate. It is definitely not being maintained.

Investigation into AT-SPI D-Bus migration

Migration of AT-SPI from Bonobo/ORBit to D-Bus is something that has already been widely discussed, both recently at the Accessibility Summit and over a the longer term with the Open A11y workgroup. Many concerns from developers about a possible move to D-Bus have gone unanswered, especially related to its performance relative to ORBit. This makes it difficult to properly evaluate the best way forward for AT-SPI.

An extended introduction and some more background can be found at Accessibility/Documentation/GNOME2/ATSPI2-Investigation/Background.

This work has generously been funded by the Mozilla foundation, and has been mentored by WillieWalker.

Performance

Orca profiling

To evaluate the performance issues we first performed some profiling of Orca.The purpose of profiling orca is to find out what the most frequent calls made over the AT-SPI interface are, and what the traffic is like in the peak periods of activity. This is so any tests on D-Bus and ORBit will approximate real world performance, and it will be possible to judge the impact of any IPC performance changes.

All of the results of the orca profiling, and a description of the tests that were run are available at:

Accessibility/Documentation/GNOME2/ATSPI2-Investigation/OrcaExtraProfiling

In brief we looked at the maximum number of calls that were made in 100ms, this was to judge how heavy the IPC usage is. We also looked at the type of calls most frequently made. The results show that there are a very large amount of AT-SPI calls taking place when running Orca. The peak number of calls over 100ms, over all the tests, was 699. It can also be seen that many of these calls come from access to only a few methods. In all but one of the tests the most frequently called method was getRole. In the period of most activity during one of the tests the top three methods (getRole, _get_parent and getChidAtIndex) accounted for 90% of all calls made.

We understand that EitanIsaacson is investigating reducing the number of AT-SPI calls made when running Orca. As such these results may change drastically with improvements to Orca. As performance tests on D-Bus need to be for the maximum possible throughput, the current results serve well as a performance baseline.

GOK profiling

Gok profiling was also performed to get a better idea about usage of the AT-SPI interface.

All of the results of the profiling, and a description of the tests are available at:

Accessibility/Documentation/GNOME2/ATSPI2-Investigation/GOKProfiling

Gok shows a similar number of calls made in peak periods to Orca. The highest number over any 100ms during the tests was 753. Although the calls are more varied, a few methods again make up the majority of calls. The makeup is similar with getRole being the most common method.

DBus and ORBit Benchmarking

Using the profiling results from orca we chose some of the most frequently called methods to look at both D-Bus and ORBit performance. All of the results as well of a description of the tests performed are available at Accessibility/Documentation/GNOME2/ATSPI2-Investigation/IPCResults. All of the code used in the test suite is located on the codethink.co.uk website: http://git.codethink.co.uk/?p=ipc-benchmarking;a=summary.

The overview tables below shows speed relative to the faster IPC mechanism for each call.

ORBit

D-Bus

getRole

1x

5.5x

getParent

1x

3x

getRelationSet

1.5x

1x

Tests were also performed when D-Bus was using a direct connection between processes rather than the session bus.

ORBit

D-Bus

getRole

1x

3x

getParent

1x

1.5x

getRelationSet

2x

1x

D-Bus is faster than ORBit at sending an object reference but slower at sending simple arguments. The speed of D-Bus is improved greatly by using a direct connection. Although orca makes a lot of getRole calls, where D-Bus performance is poor, this method may be one of the most cacheable. Many of the other frequently used method calls in orca pass object references. ORBit is likely slower at sending object references as they are a larger construct than we decided was neccessary for D-Bus. In D-Bus an object reference consisted of a bus name an object path. In ORBit an array of three strings were passed for the reference, along with a type code.

Historical Results

The Open A11y wiki mentions that D-Bus may be 18X slower than ORBit, this is certainly not what we have found. We believe that the results mentioned refer to tests performed by Frank Duignan, the report and code used can be found here. We repeated the tests detailed in the report.

Frank Duignans's tests, Original results ('C' - 'C')

D-Bus

18.7187004

ORBit

1.188036

Frank Duignans's tests, Repeated results ('C' - 'C')

D-Bus

4.3884828

ORBit

0.6710958

These are the results for one call, something similar to the getRole type signature.

These results are very interesting, as they show how D-Bus and ORBit performance have improved over time. Both the ORBit and D-Bus results have improved since the tests were originally run. ORBit performance improved reducing the time by 43%. This could be due to an improvement in the ORBit codebase, but could also be attributed to the change in computing hardware used. D-Bus however improved by a much larger amount. Taking the time from approximately 18.7s to 4.3s. This means that, for this particular call, D-Bus is no longer 18x but 6.5x slower. This is almost certainly due to an improvement in the D-Bus codebase. These results seem to differ slightly from our test suite, we think this is due to python bindings to ORBit adding more of an overhead, at least in percentage terms, to a call. In our test suite the client side was using python bindings, while this test suite used the 'C' bindings.

Architecture

Representation of the AT-SPI interface

Currently AT-SPI is defined by its IDL. It may be possible for this to continue and to translate the IDL into a D-Bus protocol specification. The disadvantage of this is that there is no well used IDL to D-Bus XML translator. Creating and maintaining one would be unnecessary work. We think the preferred solution moving forward is to redefine the AT-SPI interface as a D-Bus protocol.

Migrating AT applications

Although there are a huge amount of applications and AT programs using AT-SPI there are a smaller number of core libraries that make use directly of the ORBit bindings. These include:

  • ATK / GAIL
  • Java Access bridge
  • UNO (Or does OOo now use ATK? This needs checking)
  • cspi
  • pyatspi

The easiest move to D-Bus would require that these core libraries were rewritten to make D-Bus calls while maintaining the same interface. Luckily the AT programs use the cspi and pyatspi wrappers around ORBit, rather than direct calls. It should be possible to maintain a highly similar API to these libraries while using a D-Bus transport, although pyatspi may pose some problems as it is mostly generated from the CORBA interface definition. ATK / GAIL and the Java access bridge are both possible, with D-Bus bindings being available in both glib and Java. A D-Bus bridge for UNO is on the todo list.

The Open A11y wiki lists the parallel use of CORBA and D-Bus as a migration path. I do not think this is plausible, although it would be possible for all AT programs and applications to listen on both ORBit and D-Bus channels the work involved in would probably outweigh the benefits.

Instead there will have to be a simultaneous development of the core libraries that access ORBit AT-SPI, and testing of these libraries with AT programs and applications. When the libraries are ready a large scale switch to a D-Bus transport could be made.

D-Bus AT-SPI architecture

The architecture of AT-SPI at the moment consists of a registry daemon that is used to forward global events from either a device or an application to AT programs. Apart from this programs communicate directly using an object reference. There are a number of possible architectures for D-Bus AT-SPI.

Bus connected

In this scenario every process wishing to use AT-SPI connects to a global bus, either the D-Bus session bus, or a specific AT-SPI bus. The disadvantages of this is that there is a performance penalty when routing all messages through the bus. It requires the least amount of coding, and provides a registry daemon somewhat for free as events can simply be D-Bus signals, with applications registering to receive signals from the bus. Some work would be required to modify the bus to receive device events.

Directly connected

In this scenario a modified bus would still be required to act as a registry daemon. Method calls however would be made using direct connections between applications. This will speed up the method calls, but requires a large amount of work creating functionality to create new connections to objects, and keep track of the connections made.

Language bindings

There are language bindings to D-Bus for 'C', glib, python, perl, C++, C# and Java. QT has native D-Bus support. In terms AT-SPI the glib bindings would be used when implementing ATK/GAIL and cspi, with the python bindings used to implement pyatspi. The D-Bus glib bindings are scheduled for a large overhaul to make them easier to use. The python bindings are complete, but as performance tests have shown, may need some optimization work.

Struct representation and Object references

The D-Bus XML description originally had no notation for defining groups of arguments as a structure, such as a DeviceEvent, which would make it easy to marshal these arguments properly in language bindings. This has been rectified with extensions made at Collabora to the D-Bus XML, which they are hoping to standardize.

D-Bus currently has an object path type, but this does not equate to an object reference as there is no information about where the object can be found. The AT-SPI D-Bus specification will require some notation, preferably standardized with the D-Bus community, to represent an object reference.

Reference counting has been mentioned, as this functionality is lost along with the Bonobo interface. Reference counting of objects could be reimplemented in D-Bus although this would undoubtedly be a mistake. Most Objects in AT-SPI belong to a particular application, and when passed to an AT program should be considered a weak reference. If the application closes, the Accessible objects dissapear, regardless of whether other processes hold references.

Migration Task Breakdown

Accessibility/Documentation/GNOME2/ATSPI2-Investigation/MigrationBreakdown

Accessibility/Documentation/GNOME2/ATSPI2-Investigation/DetailedDesign

Accessibility/Documentation/GNOME2/ATSPI2-Investigation (last edited 2011-07-21 18:57:10 by JoanmarieDiggs)