Соглашение __fastcall в С#

Учитывая, что:

Специально для Майкрософт

Соглашение о вызовах __fastcall указывает, что аргументы функций должны передаваться в регистрах, когда это возможно. В следующем списке показана реализация этого соглашения о вызовах.

И что время чтения/записи в регистре намного быстрее, чем в стеке, есть ли у нас эквивалент __fastcall в C#?


person Edward    schedule 06.02.2011    source источник
comment
К вашему сведению: Fastcall быстрее?   -  person Oystein    schedule 07.02.2011


Ответы (3)


Не напрямую, С# в основном использует то, что было бы эквивалентно соглашению __stdcall MSVC++. Однако его можно «исправить», хотя и относительно грязным способом (обратите внимание, что пример для __cdecl).

Хотя, наверное, так лучше. В языке высокого уровня, таком как C# (черт возьми, даже в большинстве программ на C++), эту оптимизацию лучше оставить для компилятора. Соглашение о принудительном вызове часто может ухудшить ситуацию. И даже когда это помогает, обычно это мало что дает, по крайней мере, в программах на C и C++, где я его использовал.

person Oystein    schedule 06.02.2011

__fastcall используется автоматически, но только при определенных условиях. Вот интересная статья на эту тему:

2. В методе должно быть не более семи параметров.

Причина этого в том, что в .net первые два параметра быстрее, чем последние два параметра. Позвольте мне объяснить это более четко. В C# при каждом вызове метода параметры помещаются в стек, которые затем используются методом. Теперь компиляторы Microsoft (в X86) имеют продвинутую технику оптимизации, называемую __FASTCALL, в которой первые два параметра передаются в виде регистров. Сейчас говорят, что они зарегистрированы. Через много времени после регистрации переменная или параметр получают ускоренное продвижение с исключительным правом на сохранение в самом быстром кэше процессора. Обратите внимание, что обычно это делается с переменной «i», которую мы используем во время цикла или итерации, из-за чего доступ к ней и ее использование действительно становятся очень быстрыми. Таким образом, во время компиляции метод компилируется в собственный код средой выполнения .Net с действием __FASTCALL, поэтому метод с меньшим количеством параметров гораздо более оптимизирован, чем метод со слишком большим количеством параметров.

Источник

person Dalmas    schedule 06.02.2011
comment
Отличное объяснение Лада. Позвольте мне добавить один момент: метод с меньшим количеством параметров гораздо более оптимизирован, чем метод со слишком большим количеством. Есть ли какие-либо ограничения на тип параметров? Я имею в виду, работает ли это только с типами значений? Учитывая, что ссылочные типы хранятся в стеке. Или есть шанс, что мы сможем отправить экземпляр класса в реестр? (Извините за редактирование, опечатка) - person Edward; 07.02.2011
comment
Ссылочные типы хранятся в куче (но их адреса памяти находятся в стеке). Передача ссылочного типа в функцию в основном означает передачу его адреса памяти, это похоже на передачу указателя на функцию С++, и это просто 32- или 64-битное целое число (в зависимости от платформы), поэтому нет никаких ограничений. - person Dalmas; 07.02.2011
comment
Ну, я думаю, что есть одно ограничение: если вы передаете функции огромное значение типа, оно слишком велико для хранения в регистре... но я недостаточно знаю, чтобы рассказать вам больше о том, как компилятор справляется с этим. - person Dalmas; 07.02.2011
comment
+1 за второе отличное объяснение, я понял вашу точку зрения. Спасибо Лада - person Edward; 07.02.2011

LadaRaider, в 32-битной Arch, что означает «Максимальный размер самых больших регистров 4 байта», если вы передадите «Long Long», который занимает 8 байт, он будет использовать 2 регистра по 4 байта, вот как с этим справляется компилятор. Допустим, вы можете использовать только 3 регистра по 4 байта, поэтому вы не можете передать, например, 2 переменные «Long Long» ... Некоторые данные должны будут попасть в память, которая намного медленнее.

person Moraru Lilian    schedule 27.02.2011