Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change some delegate FCalls to managed #70000

Merged
merged 8 commits into from
May 31, 2022
Merged

Conversation

huoyaoyuan
Copy link
Member

Benchmark:

        [UnmanagedCallersOnly]
        static void X() { }

        private readonly Action _fnptr1 = Marshal.GetDelegateForFunctionPointer<Action>((nint)(delegate* unmanaged<void>)(&X));
        private readonly Action _fnptr2 = Marshal.GetDelegateForFunctionPointer<Action>((nint)(delegate* unmanaged<void>)(&X));

        private readonly Action _action1 = () => Console.WriteLine("A");
        private readonly Action _action2 = () => Console.WriteLine("B");

        private readonly Func<int> _actionInt1 = Func;
        private readonly Func<int> _actionInt2 = Func;

        public static int Func() => 42;

        [Benchmark]
        public bool UnmanagedEquals() => _fnptr1 == _fnptr2;

        [Benchmark]
        public Action Combine() => _action1 + _action2;

        [Benchmark]
        public bool ManagedEquals() => _actionInt1 == _actionInt2;
        
        [Benchmark]
        public bool ManagedNotEquals() => _action1 == _action2;

        [Benchmark]
        public bool TypeMismatch() => _action1.Equals(_actionInt1);
Method Job Toolchain Mean Error StdDev Ratio
UnmanagedEquals Job-SQNAXT \PR\corerun.exe 2.895 ns 0.0151 ns 0.0133 ns 0.50
UnmanagedEquals Job-GXCCWM \main\corerun.exe 5.844 ns 0.0553 ns 0.0490 ns 1.00
Combine Job-SQNAXT \PR\corerun.exe 42.868 ns 0.2113 ns 0.1765 ns 0.95
Combine Job-GXCCWM \main\corerun.exe 45.173 ns 0.3683 ns 0.3445 ns 1.00
ManagedEquals Job-SQNAXT \PR\corerun.exe 6.934 ns 0.0747 ns 0.0624 ns 0.58
ManagedEquals Job-GXCCWM \main\corerun.exe 11.938 ns 0.0670 ns 0.0560 ns 1.00
ManagedNotEquals Job-SQNAXT \PR\corerun.exe 94.570 ns 0.7560 ns 0.7072 ns 0.94
ManagedNotEquals Job-GXCCWM \main\corerun.exe 100.963 ns 1.5713 ns 1.4697 ns 1.00
TypeMismatch Job-SQNAXT \PR\corerun.exe 1.587 ns 0.0117 ns 0.0097 ns 0.17
TypeMismatch Job-GXCCWM \main\corerun.exe 9.482 ns 0.0368 ns 0.0326 ns 1.00

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label.

@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label May 31, 2022
@ghost
Copy link

ghost commented May 31, 2022

Tagging subscribers to this area: @dotnet/area-system-runtime
See info in area-owners.md if you want to be subscribed.

Issue Details

Benchmark:

        [UnmanagedCallersOnly]
        static void X() { }

        private readonly Action _fnptr1 = Marshal.GetDelegateForFunctionPointer<Action>((nint)(delegate* unmanaged<void>)(&X));
        private readonly Action _fnptr2 = Marshal.GetDelegateForFunctionPointer<Action>((nint)(delegate* unmanaged<void>)(&X));

        private readonly Action _action1 = () => Console.WriteLine("A");
        private readonly Action _action2 = () => Console.WriteLine("B");

        private readonly Func<int> _actionInt1 = Func;
        private readonly Func<int> _actionInt2 = Func;

        public static int Func() => 42;

        [Benchmark]
        public bool UnmanagedEquals() => _fnptr1 == _fnptr2;

        [Benchmark]
        public Action Combine() => _action1 + _action2;

        [Benchmark]
        public bool ManagedEquals() => _actionInt1 == _actionInt2;
        
        [Benchmark]
        public bool ManagedNotEquals() => _action1 == _action2;

        [Benchmark]
        public bool TypeMismatch() => _action1.Equals(_actionInt1);
Method Job Toolchain Mean Error StdDev Ratio
UnmanagedEquals Job-SQNAXT \PR\corerun.exe 2.895 ns 0.0151 ns 0.0133 ns 0.50
UnmanagedEquals Job-GXCCWM \main\corerun.exe 5.844 ns 0.0553 ns 0.0490 ns 1.00
Combine Job-SQNAXT \PR\corerun.exe 42.868 ns 0.2113 ns 0.1765 ns 0.95
Combine Job-GXCCWM \main\corerun.exe 45.173 ns 0.3683 ns 0.3445 ns 1.00
ManagedEquals Job-SQNAXT \PR\corerun.exe 6.934 ns 0.0747 ns 0.0624 ns 0.58
ManagedEquals Job-GXCCWM \main\corerun.exe 11.938 ns 0.0670 ns 0.0560 ns 1.00
ManagedNotEquals Job-SQNAXT \PR\corerun.exe 94.570 ns 0.7560 ns 0.7072 ns 0.94
ManagedNotEquals Job-GXCCWM \main\corerun.exe 100.963 ns 1.5713 ns 1.4697 ns 1.00
TypeMismatch Job-SQNAXT \PR\corerun.exe 1.587 ns 0.0117 ns 0.0097 ns 0.17
TypeMismatch Job-GXCCWM \main\corerun.exe 9.482 ns 0.0368 ns 0.0326 ns 1.00
Author: huoyaoyuan
Assignees: -
Labels:

area-System.Runtime, community-contribution

Milestone: -

FCIMPL2(FC_BOOL_RET, MethodTableNative::IsEquivalentTo, MethodTable* mta, MethodTable* mtb)
{
FCALL_CONTRACT;
FC_RETURN_BOOL(mta->IsEquivalentTo(mtb));
Copy link
Member Author

@huoyaoyuan huoyaoyuan May 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contract of IsEquivalentTo_Worker is GC_TRIGGER, so a helper method frame is still required?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps GCX_COOP is better suited for these MethodTable helpers? AFAIK, converting these FCalls to QCall (or pure managed) is a general goodness, e.g.

DllImportEntry(RuntimeMethodHandle_GetTypicalMethodDefinition)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it would be better to change this to QCall while you are on it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to pass MethodTable in QCall then? Since it's a pointer into unmanaged runtime, it should be safe to directly pass the pointer?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, pass it as pointer

@jkotas
Copy link
Member

jkotas commented May 31, 2022

The test failures are #64544 + Helix infrastructure intermittent failure.

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@jkotas jkotas merged commit b6c30d1 into dotnet:main May 31, 2022
@huoyaoyuan huoyaoyuan deleted the delegate-fcall branch June 1, 2022 04:34
@ghost ghost locked as resolved and limited conversation to collaborators Jul 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Runtime community-contribution Indicates that the PR has been added by a community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants