MerlinVR / UdonSharp

An experimental compiler for compiling C# to Udon assembly
MIT License
678 stars 89 forks source link

Inline function / (ja:) インライン関数 #49

Open ikuko opened 4 years ago

ikuko commented 4 years ago

Feature Description: Inline Functions
(ja:) 関数のインライン化

Suppose you have the following U# code (ja:) 以下のようなU#コードがあったとします

private void Start()
{
    Method();
}

void Method()
{
    Debug.Log("UDON METHOD");
}

It should compile into a UAssembly that looks like this (ja:) 以下のようなUAssemblyにコンパイルされるはず

    _start:

        PUSH, __0_const_intnl_SystemUInt32

         # {

         # Method();
        PUSH, __0_const_intnl_exitJumpLoc_UInt32
        JUMP, 0x00000244
        PUSH, __0_intnl_returnTarget_UInt32 #Function epilogue
        COPY
        JUMP_INDIRECT, __0_intnl_returnTarget_UInt32

    Method:

        PUSH, __0_const_intnl_SystemUInt32

         # {

         # Debug.Log("UDON METHOD");
        PUSH, __2_const_intnl_SystemString
        EXTERN, "UnityEngineDebug.__Log__SystemObject__SystemVoid"
        PUSH, __0_intnl_returnTarget_UInt32 #Function epilogue
        COPY
        JUMP_INDIRECT, __0_intnl_returnTarget_UInt32

It should be possible to explicitly direct it as an inline function like this (ja:) 以下のように明示的にインライン関数として指示できるようにします

private void Start()
{
    Method();
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Method()
{
    Debug.Log("UDON METHOD");
}

We believe that expanding an explicitly-directed inline function inline will improve performance by allowing some instructions to be skipped (ja:) 明示的に指示されたインライン関数をインラインに展開することによりいくつかの命令を省略することができるためパフォーマンスが向上すると考えます

    _start:

        PUSH, __0_const_intnl_SystemUInt32

         # {

         # Debug.Log("UDON METHOD");
        PUSH, __2_const_intnl_SystemString
        EXTERN, "UnityEngineDebug.__Log__SystemObject__SystemVoid"
        PUSH, __0_intnl_returnTarget_UInt32 #Function epilogue
        COPY
        JUMP_INDIRECT, __0_intnl_returnTarget_UInt32

Additional context: I manage several general purpose processes together in a common Udon. I think the use of inline functions would greatly improve performance. Many people are doing something similar because the current U# doesn't allow for static classes and static functions to be defined. I think it is. (ja:) 私はいくつかの汎用処理を共通のUdonにまとめて管理しています。インライン関数が使えるとパフォーマンスが大きく向上しそうです。現在のU#では静的クラスや静的関数の定義ができないため似たようなことをしている人は多いのではないかと思います。

MerlinVR commented 4 years ago

This is something that I want to do eventually, but is not a priority at the moment since the overhead of a local function call is lower than a single extern call usually. And with the current compiler architecture it'd involve a lot of special cases that introduce more code to maintain and more possibility for fault. At the moment U# is not an optimizing compiler and the last basic ad-hoc optimizations that were implemented also had a lot of subtle issues that caused unexpected behavior in many cases, some of which you've run into.

This is something that will happen at some point, but I want to keep the compiler as stable as possible. And in order to implement optimizations like this while minimizing risk and keeping things stable, there are some large architecture changes that need to be done first.

ikuko commented 4 years ago

I want to keep the compiler as stable as possible.

I agree. It's a true "feature request"