stdcall vs cdecl vs fastcall

Тема в разделе "WASM.ASSEMBLER", создана пользователем ravenX, 5 окт 2005.

  1. ravenX

    ravenX New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2005
    Сообщения:
    4
    Прочитал о проблемах fastcall'a де он совсем не 'fast' и замер в нерешительности.

    Народ у кого есть дельная информация о сравнительной скорости\проблемах. Какую конвенцию лучше использовать в глубинах своего кода?
     
  2. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257




    Что же это за проблемы такие? Передать два параметра не через стек, а в регистрах eax/edx? Что здесь проблематичного, кроме необходимости помнить, что fastcall, а не stdcall?
     
  3. Sergey_R

    Sergey_R Member

    Публикаций:
    0
    Регистрация:
    9 янв 2005
    Сообщения:
    138
    Реальная проблема (во всяком случае, из тех, которые мне известны) лишь в том, что fastcall не столь стандартизирован, как cdecl или stdcall - в компиляторах Microsoft и Borland (Watcom тоже, но про него я знаю мало) он реализован по разному:

    - Microsoft: передача первых двух параметров в регистрах ecx и edx, остальные через стек справа-налево (как cdecl или stdcall);

    - Borland: передача первых трех параметров в регистрах eax, edx и ecx, остальные через стек _слева-направо_ (как pascal; читал, что Borland впервые ввела этот тип в Delphi).

    В результате могут возникнуть сложности при использовании библиотек РАЗНЫХ компиляторов. Хотя, fastcall практически не используется для экспорта, так что вероятность нарваться на такое невелика. Ну а
    об этом можно и не задумываться. ;о)



    Относительно проблем со скоростью, так это как поглядеть. Вот здесь - http://www.tantalon.com/pete/cppopt/compiler.htm#FastCall - например, утверждается, что в типичных приложениях fastcall на ~2% (! :o)) быстрее cdecl. Можно выиграть в скорости, создавая безфреймовые функции. С другой стороны, вызываемая функция может "испортить" содержимое регистра, следовательно, его требуется где-то сохранять, а это тоже потеря...

    Так что все зависит от обстоятельств. Дать "глобальный" :о) совет тут невозможно.
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    В своём коде можно делать как угодно. Это же ассемблер.

    Вспомним классику:



    «Параметры можно передавать с помощью одного из шести механизмов:

    <ul type=disc>

    <li>по значению;

    <li>по ссылке;

    <li>по возвращаемому значению;

    <li>по результату;

    <li>по имени;

    <li>отложенным вычислением.

    </ul>



    Параметры можно передавать в одном из пяти мест:

    <ul type=disc>

    <li>в регистрах;

    <li>в глобальных переменных;

    <li>в стеке;

    <li>в потоке кода;

    <li>в блоке параметров.

    </ul>

    »



    Зубков.
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    SErgey_R

    > "вызываемая функция может "испортить" содержимое регистра"

    Регистров мало, поэтому eax,ecx,edx она запортит с вероятностью ~99.9(9)% ;)

    А вот суммарный выигрыш от fastcall действительно мизерный, т.к. кроме жалких 2-3х push\mov "типичная функция типичного приложения" выполняет массу других полезных и более трудоемких действий
     
  6. ravenX

    ravenX New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2005
    Сообщения:
    4
    Извините за неточность формулировки. Под fastcall'ом имел в виду передачу параметров в регистрах(любых: ecx,r27,xmm0 или каких там еще) и передачу их в стеке(stdcall/cdecl)



    Сформулирую вопрос иначе. Я не спрашиваю как работает fastcall Borland/Microsoft etc Я хотел найти инфу о проблемах передачи параметров в регистрах вообще(fastcall) по сравнению с передачей их в стеке(stdcall/cdecl). Прочитал где-то что при вызовах большого уровня вложенности и малых размерах функций издержки fastcall'a превышают stdcall'ные. Фреймовость/безфреймовость тут не при чем. Хотел бы узнать механизм этого явления и сделать выводы для написания собственного кода.
     
  7. rst

    rst New Member

    Публикаций:
    0
    Регистрация:
    5 май 2003
    Сообщения:
    165
    ravenX - ну дык конечно будут издержки в случае fastcall и рекурсии.

    Т.к. все функции используют фактически одну и ту же область памяти для передачи параметров (регистры), то перед вызовом функции их нужно куда-то сохранять. Соответственно компилятор скорее всего генерирует нечто типа pusha/popa

    А вообще - что за вопросы. Возьми пару компилеров сделай рекурсивную функцию с fastcall и посмотри сгенерированный код.



    Кстати. Касательно плюсов и минусов.

    Использование в ядре 2.6 fastcall, а так же использование при компиляции софта MMX регистров для передачи параметров - дает весьма заметный прирост производительности на linux-системах.
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    ravenX

    Разумеется fastcall имеет смысл, когда функция сразу использует данные в регистрах по назначению без необходимости их пушить в стек, а затем заново извлекать. А если в начале функции идет вызов API или чего другого, то регистры приходится все равно пушить\попить, если они еще понадобятся.

    Поэтому подход должен быть индивидуальным. Fastcall рулит для простых и быстрых функций, которые сразу используют переданные параметры без необходимости их пушить в стек. Если же регистры приходится пушить, или функция имеет большое число параметров, или работает она сравнительно долго, то fastcall ничего хорошего не дает.

    Еще кстати при fastcall можно оптимально с точки зрения логики функции задавать последовательность передачи параметров (что в какой регистр, что в стек), хоть это может выглядеть и не совсем логично с точки зрения объявления прототипа
     
  9. ravenEx

    ravenEx New Member

    Публикаций:
    0
    Регистрация:
    8 окт 2005
    Сообщения:
    18
    2 rst

    Я сам генерирую код:)Сл-но брать и тестировать компилеры мне не надо.

    2 leo

    Ммм. До этого можно и своим умом дойти. А на более "фундаментальные" исследования ссылоки не дашь?

    P.S. ravenX это я(просьба к админам удалить аккаунт тк я пароль посеял)
     
  10. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine


    Что, и мыло тоже посеял?