Указать настройки Cmake для х64

Тема в разделе "WASM.SOFTWARE", создана пользователем M0rg0t, 31 дек 2020.

  1. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    Есть проект, который собирается с помощью Cmake компилятором студии. В нем есть такая строка:

    Код (Text):
    1. set(COMPILE_OPTIONS
    2.     /W3 /Ox /Ob2 /Os /GF /MD /GS- /Gy /MP
    3.     $<$<CONFIG:Debug>:/Zi>
    4.     /arch:$<IF:$<BOOL:${CMAKE_CL_64}>,AVX,SSE>)
    Кто может подсказать по таким вопросам:
    1. Что значит строка "/arch:$<IF:$<BOOL:${CMAKE_CL_64}>,AVX,SSE>) " ? Если компилятор 64 битный, то собирать с поддержкой AVX? А если 32 битный, то будет SSE или ничего?

    2. Почему, когда собираешь с поддержкой AVX 64 битную прогу, она крашится на виртуалках? Какой-то инструкции там нет или что? И как это можно обойти, что указать чтобы собиралось нормально?
     
  2. darkdevel

    darkdevel New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2017
    Сообщения:
    17
    1. Если компилятор 64 битный, то собирать с поддержкой AVX, а если 32 битный, то будет SSE.
    2. Должно работать. Надо посмотреть код исключения при вылете, если действительно 0xC000001D (invalid instruction code), то, вероятно, очень древняя виртуалка, пора обновляться.
     
  3. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    darkdevel, по пункту 2 - падает на инструкции вида
    Код (ASM):
    1. vpxor xmm0, xmm0, xmm0
    , вроде не очень древние ВМ, а в 2018 году и на динчеке падало.
    менял в настройках проекта на /arch:IA32 , работает вроде, но решение так себе, имхо.
     
  4. darkdevel

    darkdevel New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2017
    Сообщения:
    17
    ОС, конечно, 7 с SP или новее. А какая виртуалка? У меня VMware, в ней надо не забывать обновлять Hardware Compatibility гостевых ОС.
    Кстати, а соответствующий бит в cpuid выставлен? Если нет, то нечего и вызывать неизвестные инструкции ;)
     
  5. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    darkdevel, виртуалбокс.

    так я откуда знаю, я же не на Асме пишу; все вопросы к студии, че она там вставляет.
     
  6. Carnival

    Carnival New Member

    Публикаций:
    0
    Регистрация:
    31 дек 2020
    Сообщения:
    26
    Адрес:
    ::1/128
    Имеется ввиду что когда набор инструкций (AVX, SSE и др) поддерживается процессором он в cpuid выставляет определенные биты (какие именно можно смотреть в мануалах), таким образом по этим битам можно проверить поддерживаются ли инструкции.
     
  7. darkdevel

    darkdevel New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2017
    Сообщения:
    17
    Все верно, подробнее и понятным языком описано на SO: https://stackoverflow.com/questions...pport-require-which-cpu-multimedia-extensions
    Использовать асм не придется, в компиляторе студии предусмотрены intrinsics: https://docs.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex и даже есть WinAPI https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getenabledxstatefeatures
    Для коммерческого софта хорошим тоном будет проверить набор инструкций и заранее сообщить end-user, что его железо не соответствует системным требованиям, либо иметь две реализации алгоритма. Инструкции не самые новые, но какие только конфигурации не попадаются при саппорте, даже на васме есть адепты секты ХР.

    Виртуалбоксом не пользовался, но пишут, что можно проверить так: VBoxManage getextradata $VMname enumerate, дальше смотрим VBoxInternal/CPUM/IsaExts/AVX2
     
  8. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    Carnival, darkdevel, спасибо. Значит, надо отключать это в студии и всё.

    студия не проверяет ничего, тупо вставляет эти инструкции.
     
  9. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Интересно взглянуть на код ошибки: если AVX поддерживается физическим процессором, он будет поддерживаться и виртуальным, и отключить поддержку расширений нельзя.
    Даже если сбросить биты в CPUID, отвечающие за SSE/AVX/etc., эти инструкции всё равно будут доступны для выполнения.
    Покажи код ошибки и ассемблерный кусок, где вылетает эксепшн (и отметь там RIP) - возможно, падает не из-за виртуалки или не там, где думаешь.
     
  10. darkdevel

    darkdevel New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2017
    Сообщения:
    17
    VirtualBox в мануалах предлагает отключение различных расширений, как пример:
    To provide SSE 4.1/SSE 4.2 support to guests, the host CPU has to implement these instruction sets. The instruction sets are exposed to guests by default, but it is possible to disable the instructions for certain guests by using the following commands:
    $ VBoxManage setextradata VM-name \
    VBoxInternal/CPUM/IsaExts/SSE4.1 0
    $ VBoxManage setextradata VM-name \
    VBoxInternal/CPUM/IsaExts/SSE4.2 0
    These are per-VM settings which are enabled by default.
    Я сам не пользовался VirtualBox, но не вижу проблемы программно реализовать подобную фичу: поставить маски в контрольных регистрах гостевой ОС.
    Если ОС не поставила биты, подтверждающие поддержку того или иного instruction set, то процессор будет вести себя, как будто "не умеет": генерировать #ud.

    Если указываешь компилятору использовать расширенный набор инструкций, добавь проверку сам, без опции компилятор не будет вставлять лишнего (хотя после перехода разработки VS на Agile какие там только баги не встречаются).
     
  11. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Да, был не прав, действительно так можно.
    Screenshot_20210110-120551_Adobe Acrobat.jpg
     
  12. darkdevel

    darkdevel New Member

    Публикаций:
    0
    Регистрация:
    31 июл 2017
    Сообщения:
    17
    Кстати, нагуглился очень простой способ проверить поддержку инструкций в рантайме:
    Код (C):
    1. #include <stdio.h> extern "C" int __isa_available; int main() { printf("__isa_available: %d\n", __isa_available); }
    Значения переменной как раз соответствуют опциям компилятора:
    Код (C):
    1. enum ISA_AVAILABILITY
    2. {
    3.     __ISA_AVAILABLE_X86   = 0,
    4.     __ISA_AVAILABLE_SSE2  = 1,
    5.     __ISA_AVAILABLE_SSE42 = 2,
    6.     __ISA_AVAILABLE_AVX   = 3,
    7.     __ISA_AVAILABLE_ENFSTRG = 4,
    8.     __ISA_AVAILABLE_AVX2 = 5,
    9.     __ISA_AVAILABLE_AVX512 = 6,
    10. };
    Или развернутый вариант с cpuid:
    https://github.com/Mysticial/FeatureDetector

    Имхо, надо пользоваться современными инструкциями везде, где это возможно.
    Если еще не окончательно забил на изначальный вопрос, запусти детектор на хосте и в госте. Думаю, проблема в конкретной виртуалке.
     
    hiddy и Mikl___ нравится это.
  13. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    Вернулся к этому вопросу, хотя вижу, что проще забить и отключить..
    Вот скрин. Примерно так падает. 2012 винда.

    Я все равно не пойму; ну вот собрал я ехе , там уже есть внутри эти новые инструкции. Это же не питон или какой-то JIT, что даст проверка? Я же не могу знать, будет это на машине юзера или нет.
     

    Вложения:

    • Снимок.PNG
      Снимок.PNG
      Размер файла:
      116,2 КБ
      Просмотров:
      186
  14. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    А эксепшн с каким кодом? На скрине не видно
     
  15. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    HoShiMin, EXCEPTION_ILLEGAL_INSTRUCTION
     
  16. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    Кто знает, как добавить в CMAKE инклуд .def файла? Что-то смотрел в документации, ничего не работает. Суть - есть проект, который билдится этим самым cmake, и нужно чтобы в дллке был экспорт . Если просто в коде указать через declspec dllexport, то функция экспортируется вида в формате с _Function@4 , что неприемлемо. Только деф файл дает как надо имя (Function).
     
  17. njeen

    njeen Active Member

    Публикаций:
    0
    Регистрация:
    26 мар 2017
    Сообщения:
    139
    Адрес:
    Ташлинск
    Если очень хочется сделать dll именно с def файлом, то так же, как и обычно -
    передать в опции линкеру. Например, для студии будет так:
    Код (Text):
    1.  
    2. if ( MSVC )
    3.     set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}  /def:${CMAKE_CURRENT_SOURCE_DIR}/exp.def")
    4. endif ()
    5.  
    Здесь exp.def лежит в той же папке (CMAKE_CURRENT_SOURCE_DIR), что и
    CMakeLists.txt у dll. Поэтому здесь путь для линкера сделан относительно этой
    директории.

    Но вообще, странное желание. Обычно для подавления манглинга при экспорте используют обрамление extern "C" :
    Код (Text):
    1.  
    2. extern "C"
    3. {
    4.     __declspec(dllexport) int myfn(){return 0;};
    5. };
    6.  
     
    M0rg0t нравится это.
  18. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.576
    Разве это поможет? У меня код на Си , а не на плюсах.
    По опциям попробую, спасибо.
    --- Сообщение объединено, 26 фев 2021 ---
    njeen, в общем, если в Си написать так
    Код (C):
    1. __declspec(dllexport) int WINAPI myfn(int a) { return 0; };
    то будет имя с манглингом. А без WINAPI будет норм.
     
  19. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    Ну ты понимаешь, что с WINAPI будет stdcall, а без WINAPI cdecl (мы же x86 обсуждаем)? Если тебя это устраивает, то окей, но у клиентов, которые будут вызывать твою библиотеку должны быть верные прототипы функций (с твоей конвенцией вызовов).
    --- Сообщение объединено, 26 фев 2021 ---
    У GCC есть параметр --kill-at для линкера, который у экспортируемых стдколл функций убирает постфикс @<N>, наверное у студии тоже что-то такое есть, можешь это передать, как дополнительный параметр для линкера.
     
  20. njeen

    njeen Active Member

    Публикаций:
    0
    Регистрация:
    26 мар 2017
    Сообщения:
    139
    Адрес:
    Ташлинск
    Нет, не поможет, это только для c++.

    WINAPI означает stdcall соглашение - декорируется по-другому имя. Не указано - cdecl. Убирать просто так нельзя