Engine updates
"Thong (Tum) Nguyen" <tum-x2aT3/[email protected]>
| Newsgroups | gmane.comp.gnu.dotgnu.developer |
|---|---|
| Message-ID | <[email protected]> |
Hi folks, I just wanted to give everyone an update on the things I've been working on in the past couple of weeks. Hopefully this message will help make the developers list look busy and attract more developers :D! Monitors -------- Monitors are now much faster than they were in 0.1. Thanks to ideas and encouragement from Russell Stuart and a few optimisations and simplifications of the algorithm, the code runs several orders of magnitude faster than the monitors in 0.1 (by my tests, over 200 times faster). This should speed up the class library in general. Here's some brief very unscientific benchmarks for the new monitors against a commercial .NET VM. Test PNET Commercial VM Uncontested no lock 33,695,060 313,115,470 Uncontested 6,612,628 30,750,238 Contested recursive 6,323,352 29,521,962 Contested-2-threads 6,669,712 25,270,728 The test is a loop that increments a counter. The no lock test is for comparison. Observations: PNET is about 1/5th the speed when counting with locks compared to when counting without. The commercial VM is about 1/10th the speed when counting with locks compared to when counting without. When not using locks, PNET is 1/10th the speed of the commercial VM. When using locks, PNET is 1/5th the speed of the commercial VM. Probably doesn't mean much since we're comparing a JIT to an unroller but I think it does indicate that PNET monitors show promise. This is especially true when you consider that MS.NET monitors are broken. For example, MS.NET won't throw a ThreadStateException when you exit a monitor without entering it. PNET supports two methods of associating monitors with objects. The standard method stores a pointer to the monitor in the object header. The "thin-lock" method uses a hashtable to associate the monitor with the object. The standard method is faster but requires an extra word for every object even if the object is never used for synchronization. The thin-lock method is slower but doesn't require an extra word for every object so is better on platforms with limited memory or with programs that create thousands (or millions) of tiny objects or with programs that don't use make much use of synchronization (remember: pnetlib uses synchronization). The monitor enter/exit algorithms are designed to eliminate context switches into kernel mode by avoiding "fat" OS-locks (therefore avoiding system calls) and as I mentioned above, are now much faster than they were before. You can enable thin-locks by configuring pnet with the full-tl profile ./configure --with-profile=full-tl I think Portable.NET is currently the only .NET VM to offer thin-locks. Thin-lock support is inline with one of Portable.NET's biggest advantages: its ability to run on small devices with limited memory. Threading --------- Lots of improvements here. The threading stuff in pnet/support is stabilising nicely -- lots of sneaky race conditions have been eliminated thanks to tests from Russell. Interrupt and Abort support has been touched up and they are now in a more usable state ;-). Interlocked functions have been movied to the libsupport and the x86 versions of these functions have been optimised using assembly. It would help if some volunteers could come along and write PPC/MIPs/SPARC/etc versions of these functions. Delegate.DynamicInvoke/Method.Invoke ------------------------------------ You can now invoke methods with out/ref parameters and get those parameters back :-). The out/ref parameters will be passed back through the parameter array. One interesting thing I learnt is that .NET allows you to pass nulls as arguments to functions that require valuetypes (or valuetypes byref). The nulls are converted by the runtime into empty value-types of the corresponding type. AFAIK, this is undocumented and mono throws an NullReferenceException instead. I've made PNET's behaviour mirror MS.NET. Asynchronous delegates/methods ------------------------------ Asynchronous method calls (via delegates) now work -- including the ability to retrieve out/ref parameters in the call to Delegate.EndInvoke. Out/ref parameters will be passed back into the stack/fields just like with any other method call. GC -- Foundations for typed allocation have been laid (see include/il_gc.h). Typed-allocation will allow us to decrease the chances that objects won't be collected or finalized by letting us tell the GC which words within an object contain pointers and which don't. All the best, ^Tum