Какие стандартные методы существуют для использования специфичных для процессора функций в библиотеках DLL?

StackOverflow https://stackoverflow.com/questions/131128

  •  02-07-2019
  •  | 
  •  

Вопрос

Сокращенная версия:Мне интересно, возможно ли и как лучше всего использовать специфические для процессора инструкции в библиотеке DLL?

Немного более длинная версия:При загрузке (32-битных) библиотек DLL, скажем, из Microsoft кажется, что один размер подходит для всех процессоров.

Означает ли это, что они строго построены для наименьшего общего знаменателя (т.е. минимальная платформа, поддерживаемая операционной системой)?Или есть какой-то метод, который используется для экспорта одного интерфейса в DLL но использовать Код конкретного процессора за кулисами, чтобы получить оптимальную производительность?И если да, то как это делается?

Это было полезно?

Решение

Я не знаю ни о каком таком стандартный техника, но если бы мне пришлось создать такую вещь, я бы написал некоторый код в функции DllMain() для определения типа процессора и заполнения таблицы переходов указателями функций на оптимизированные для процессора версии каждой функции.

Также должна быть функция наименьшего общего знаменателя для случаев, когда тип процессора неизвестен.

Вы можете найти текущую информацию о процессоре в реестре здесь:

HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor

Другие советы

Ожидается, что библиотека DLL будет работать на каждом компьютере, на котором работает WIN32, поэтому в целом вы придерживаетесь набора инструкций i386.Официального метода предоставления функциональности / кода для конкретных наборов инструкций не существует.Вы должны делать это вручную и прозрачно.

Используемая техника в основном заключается в следующем:- определите функции процессора, такие как MMX, SSE, во время выполнения - если они присутствуют, используйте их, если нет, подготовьте резервный код

Поскольку вы не можете позволить своему компилятору оптимизировать что-либо еще, кроме i386, вам придется писать код, используя определенные наборы команд во встроенном ассемблере.Я не знаю, существуют ли для этого инструменты на более высоком языке.Определение характеристик процессора является простым делом, но также может потребоваться выполнить его на ассемблере.

Простой способ получить оптимизацию SSE / SSE2 - это просто использовать /arch аргумент в пользу MSVC.Я бы не стал беспокоиться о резервном варианте - нет причин поддерживать что-либо ниже этого, если только у вас нет очень узкоспециализированного приложения.

http://msdn.microsoft.com/en-us/library/7t5yh4fd.aspx

Я полагаю, что gcc / g ++ имеют эквивалентные флаги.

ICC Intel может компилировать код дважды, для разных архитектур.Таким образом, вы сможете получить свой торт и съесть его.(Хорошо, вы получите два пирожных - ваша библиотека DLL будет больше).И даже MSVC2005 может сделать это для очень специфических случаев (например.memcpy() может использовать SSE4)

Существует множество способов переключения между различными версиями.Загружается библиотека DLL, потому что процессу загрузки нужны функции из нее.Имена функций преобразуются в адреса.Одно из решений состоит в том, чтобы позволить этому поиску зависеть не только от имени функции, но и от характеристик процессора.Другой метод использует тот факт, что функция name to address использует таблицу указателей на промежуточном шаге;вы можете поменять местами всю таблицу целиком.Или у вас даже может быть ветвь внутри критических функций;итак, foo() вызывает foo__sse4, когда это быстрее.

Библиотеки DLL, загружаемые вами из Microsoft, предназначены для универсальной архитектуры x86 по той простой причине, что они должны работать на всем множестве существующих компьютеров.

До выпуска Visual Studio 6.0 временные рамки (я не знаю, изменились ли они) Microsoft использовала для оптимизации своих библиотек DLL размер, а не скорость.Это связано с тем, что уменьшение общего размера библиотеки DLL дало более высокий прирост производительности, чем любая другая оптимизация, которую мог сгенерировать компилятор.Это связано с тем, что ускорение за счет микрооптимизации было бы явно низким по сравнению с ускорением за счет того, что процессор не ожидал загрузки памяти.Истинное повышение скорости происходит за счет сокращения ввода-вывода или улучшения базового алгоритма.

Только несколько критических циклов, которые выполняются в центре программы, могут извлечь выгоду из микрооптимизации просто из-за огромного количества раз, когда они вызываются.Только около 5-10% вашего кода может попасть в эту категорию.Вы могли бы быть уверены, что такие критические циклы уже были бы оптимизированы инженерами-программистами Microsoft на ассемблере до определенного уровня и не оставили бы многого после себя для поиска компилятором.(Я знаю, что они ожидают слишком многого, но я надеюсь, что они это сделают)

Как вы можете видеть, были бы только недостатки от увеличенного кода DLL, который включает дополнительные версии кода, настроенные для разных архитектур, когда большая часть этого кода редко используется / никогда не является частью критического кода, который потребляет большую часть циклов вашего процессора.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top