Home

Awesome

Fast delegates implementation

Summary

The intention of this project is to make a fast implementation in C++17 that will work on multiple platforms at maximum speed.

The main code is in delegate.h and delegate.cpp, abi.h contains ABI feature macros, and main.cpp contains some test cases to exercise the code.

Status so far:

CompilerVersionOSStatus
MinGW GCC10.3.0 x86_64WindowsMAME_DELEGATE_TYPE_ITANIUM
MinGW GCC10.3.0 i686WindowsMAME_DELEGATE_TYPE_COMPATIBLE
MinGW clang12.0.0 x86_64WindowsMAME_DELEGATE_TYPE_ITANIUM
MinGW clang12.0.0 i686WindowsMAME_DELEGATE_TYPE_COMPATIBLE
clang-cl12.0.0 x64WindowsMAME_DELEGATE_TYPE_MSVC crash at Num=6
clang-cl12.0.0 x86WindowsMAME_DELEGATE_TYPE_COMPATIBLE
MSVC19.29 x64WindowsMAME_DELEGATE_TYPE_MSVC crash at Num=6
MSVC19.29 x86WindowsMAME_DELEGATE_TYPE_COMPATIBLE
GCC8.3.1 x86_64LinuxMAME_DELEGATE_TYPE_ITANIUM
GCC8.3.1 i686LinuxMAME_DELEGATE_TYPE_ITANIUM
GCC10.2.1 armhfLinuxMAME_DELEGATE_TYPE_ITANIUM
clang6.0.1 x86_64LinuxMAME_DELEGATE_TYPE_ITANIUM
clang6.0.1 i686LinuxMAME_DELEGATE_TYPE_ITANIUM
clang11.0.1 armhfLinuxMAME_DELEGATE_TYPE_ITANIUM

Ultimately, situations where MAME_DELEGATE_TYPE_COMPATIBLE is used should be minimised.

Benchmarks

Note that the benchmarks are outdated.

Doing 100000000 to a virtual method

     typedef delegate<void(int j)> callback_delegate;
     callback_delegate cb = callback_delegate(FUNC(MyClass2::docount), &mc);

     typedef std::function<void(int)> callback_delegate_std;
     callback_delegate_std  cb_std = std::bind(&MyClass2::docount, &mc, std::placeholders::_1);

Please note that times will be different from run to run, but values are near

CompilerVersionOSTime fast delegates native (ns)Time std::function/bind (ns)
MinGW GCC5.3.0 x64Windows131547400216178100
MinGW GCC5.3.0 x86Windows131160000285218800
Clang3.8.0 x64Windows100766900219475700
Clang3.8.0 x86Windows
GCC4.9.2 ARMLinux (RasPi2)11209243214146617167
GCC5.3.1 x64Linux139180356205068909
Clang3.7.0 x64Linux140548960182060144
Clang Apple7.3.0 x64OSX125145702262906798
VS2015x64Windows
VS2015x86Windows
GCC5.3.1 ARM64Linux (Odroid-C2)6541856711370827564
GCC4.9.2 MIPSELLinux (Creator Ci20)10027937053341533518

Windows machine Intel i7-4790K @4.00GHz

Description

There are many implementations of delegate-like functionality for C++ code, but none of them is a perfect drop-in fit for use in MAME. In order to be useful in MAME, we need the following properties:

Thus, the implementations below are based on existing works but are really a new implementation that is specific to MAME.


The "compatible" version of delegates is based on an implementation from Sergey Ryazanov, found here:

https://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates

These delegates essentially generate a templated static stub function for each target function. The static function takes the first parameter, uses it as the object pointer, and calls through the member function. For static functions, the stub is compatible with the signature of a static function, so we just set the stub directly.

Pros:

Cons:


The "Itanium" version of delegates makes use of the internal structure of member function pointers in order to convert them at binding time into simple static function pointers. This only works on platforms where object->func(p1, p2) is equivalent in calling convention to func(object, p1, p2).

Pros:

Cons:


The "MSVC" version of delegates makes use of the internal structure of member function pointers in order to convert them at binding time into simple static function pointers. This only works on platforms where object->func(p1, p2) is equivalent in calling convention to func(object, p1, p2).

Pros:

Cons:


Further reading:

License (BSD-3-clause)

<a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank"> <img align="right" src="http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png"> </a>
Copyright 2010-2022 Aaron Giles, Couriersud, Miodrag Milanovic, Vas Crabb.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

   1. Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.

   2. Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.