[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 1.1.8.1, (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
--
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