[Mono-dev] Fast Virtual Generic Method Calls

Mark Probst mark.probst at gmail.com
Fri Jul 18 14:48:07 EDT 2008

Hi everybody,

I've improved the implementation of virtual generic method calls, at
least in terms of speed.  Now I'd like to ask if anybody knows of
reasonably easy to install applications which use virtual generic
methods extensively, so that I can test and improve the code with
real-world examples.

Previously doing a virtual generic call involved calling an unmanaged
function which did the look-up, so it was rather slow.  My
implementation uses the runtime generic context infrastructure I
developed for generic code sharing.  Note that it does not require
generic code sharing to be turned on to work (actually it's faster
without it).  Note also that the optimization doesn't apply to
interface calls.  Unfortunately, the memory usage of my implementation
is (still) unreasonably high (see below).  I'm working on that.

Still, I've included the patch and a simple benchmark program.

What the benchmark does is run three different but very similar loops
100 million times each.  The loops differ in that one does no calls,
one does a non-generic virtual call each iteration and one does a
generic virtual call each iteration.  It prints out the time in
nanoseconds for one iteration for each loop and then the difference of
the last two loops to the first, i.e. the costs of the method calls.
Here's what I get on my machine (x86) before my patch:

no calls: 32.34614
non-generic calls: 36.13996
generic calls: 691.26125

non-generic call cost: 3.79382
generic call cost: 658.91511

This is what I get with my patch and generic sharing turned on for all classes:

no calls: 32.59865
non-generic calls: 36.07583
generic calls: 42.34147

non-generic call cost: 3.47718
generic call cost: 9.74282

This is what I get on the same machine with Microsoft's CLR:

no calls: 18.90625
non-generic calls: 31.40625
generic calls: 52.96875

non-generic call cost: 12.5
generic call cost: 34.0625

The huge difference in the relations is probably a sign of the
crudeness of the benchmark, but I think we're competitive now, to say
the least.

The speed gained comes at the cost of memory used by the (M)RGCTXes.
I have two applications which make use of virtual generic methods,
namely IronPython2 and F#2.  Here's what's going on there, with full
generic code sharing enabled:

IronPython2 (running pystone):
  generic virtual calls w/o patch: 138
  slow generic virtual calls with patch: 47
  (M)RGCTX memory usage w/o patch: 43.5k
  (M)RGCTX memory usage with patch: 45.5k

F#2 (compiling a simple program):
  generic virtual calls w/o patch: 2421
  slow generic virtual calls with patch: 0
  (M)RGCTX memory usage w/o patch: 242k
  (M)RGCTX memory usage with patch: 288k

If I run the F# benchmark without generic sharing the memory used by
(M)RGCTXes is about 17k, all of which is completely due to the virtual
generic method call optimization.  It seems that there are 64
different instantiations of virtual generic methods called in that

-------------- next part --------------
A non-text attachment was scrubbed...
Name: fast_virtual_generic_calls.diff
Type: text/x-diff
Size: 19928 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20080718/1721b846/attachment-0001.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: vgmbench.cs
Type: application/octet-stream
Size: 2899 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20080718/1721b846/attachment-0001.obj 

More information about the Mono-devel-list mailing list