[Mono-dev] embedded runtime questions

Allan Hsu allan at counterpop.net
Fri Sep 9 17:06:00 EDT 2005

Some of us from imeem will be at PDC next week and we'll definitely  
be at the Mono meeting on Tuesday. I'd love to meet some of you guys  
and provide a look at what we're doing with Mono.

Now, on to some questions I have regarding the Mono embedded C API:

1. Under the Mono, (most recent release made for OS X), the  
instructions from the Wiki entry  (http://mono-project.com/ 
Embedding_Mono#Threading_issues) to call mono_thread_attach don't  
work in all situations. I get an error telling me to include <gc.h>  
before <pthread.h>, which is impossible for me to do in the cases  
where the current thread was not created by my own code.

Instead, I've been using mono_thread_create in an Objective-C  
NSThread poser class. Is it safe to do this? This function is not  
mentioned in the Wiki entry. If so, is there any additional setup/ 
teardown I need to perform? It seems to work, but I'm unsure as to  
whether or not I'm being totally clean about it.

2. Is there a facility to get a MonoMethod* that is more specific  
than mono_class_get_method_from_name? This works fine until you have  
multiple methods with the same name and the same number of arguments.  
I've been able to work around the problems I've had by tweaking my C#  
code (renaming methods, etc), but I could see this being a problem  
for people that are calling into corlib or other C# assemblies that  
are not their own.

3. Is there any way to reduce method invocation overhead past caching  
MonoMethod*s? I notice that mono_jit_runtime_invoke in mini.c emits  
and compiles an invocation wrapper with this function prototype:

MonoObject *(*runtime_invoke) (MonoObject *this, void **params,  
MonoObject **exc, void* compiled_method);

As far as I can tell, every time mono_jit_runtime_invoke is called,  
it has to make sure that the MonoMethod in question is inflated and  
JITed and that it there is also an invocation wrapper emitted and  
JITed before actually calling the runtime_invoke function. I would  
love to be able to cache pointers to both the compiled method as well  
as the invocation wrapper, so that I could do something like this,  
avoiding the lookup overhead in mono_jit_runtime_invoke:

MonoObject *result = someCachedRuntimeInvoke(someObject, monoArgs,  
&monoException, someCachedCompiledMethod);

Even better would be if it were possible to JIT the invocation  
wrapper in such a way that saving a pointer to the compiled method  
were not necessary.

Here are some of my informal benchmarking numbers on function calling/ 
message passing/method invocation overhead on a 2Ghz G5 iMac. The  
numbers are average call times for nop methods called several hundred  
thousand times:

Objective-C message passing: ~.055 usec
C# method calls: ~0.04 usec
Full, non-cached embedded Mono C API lookup/invocation (parent  
lookup, etc): ~6 usec
locally saved Mono C API (using the same MonoMethod* over and over):  
~2.9 usec
self-written caching, using Judy Arrays: ~3.2 usec

I'm currently using a caching scheme that uses (MonoClass*, method  
name, number of arguments) as a key that maps to MonoMethod*  
pointers. I'm hoping I can reduce call overhead further by mapping  
the same key straight to function pointers. What do you think? The  
unmanaged thunk proposal in the embedding page sounds interesting,  
but I'd be happy with something more complicated.

See you guys next week at PDC.

Allan Hsu <allan at counterpop dot net>
1E64 E20F 34D9 CBA7 1300  1457 AC37 CBBB 0E92 C779

More information about the Mono-devel-list mailing list