tags:

views:

273

answers:

3
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern double Sin(double a);

What are the reasons for this?

+4  A: 

Most likely because the implementation is optimized native code.

Joren
+10  A: 

MethodImplOptions.InternalCall means the method is implemented natively by the common language runtime. It makes sense for mathematical operations as they are usually heavily optimized for the target platform. For instance, in x86 architecture, there is a single instruction that computes sine and cosine. A managed implementation is unlikely to be able to directly utilize such instructions.

Mehrdad Afshari
Thanks Mehrdad, by natively you mean C++ or NGEN'ed C#, or something else?
Joan Venge
@Joan: No, I don't mean NGENed. When such a method is invoked, the CLR uses it's own implementation (most likely C++ or assembly). The method implementation is a part of the CLR code.
Mehrdad Afshari
Thanks maybe a little unrelated by I have 2 questions. 1. Is such a method like Sin is written for so many different platforms separately? And how does the compiler and CLR makes sure there is actually an internal call for it at compile time and at runtime. Would this be visible in IL or is it all under the hood magic?
Joan Venge
1. Most likely, they have optimized it for each architecture. Even if they simply call `sin` in unmanaged C standard library, the call is optimized by the compiler compiling the CLR code base. 2. The attribute is certainly visible in IL but there's no IL for the *body* of the method at all. As I said, the method is part of the CLR so it has intimate knowledge of methods that it has implemented. The JIT compiler will replace the call with its own method when it sees such a method.
Mehrdad Afshari
Thanks Mehrdad, last question. CLR is written in unmanaged C?
Joan Venge
I think, based on what I've seen from the Rotor source code, the Microsoft implementation is in C++ for the most part; and of course it's unmanaged.
Mehrdad Afshari
This is a typical pattern for math operations and also operations that can benefit from SSE instructions.
Steve
+2  A: 

The implementation is done in native. This is not just for Sin, look also at the common string operations.

The CLR is aware of such methods, and it maintains a "call table". When it sees the call from Math.Sin it redirects it to the native implementation by "lookup" into the call table. If you want to find more, search for ecall.cpp in the rotor sources, or go directly here (google code search).

Ion Todirel