_BitScanForward в C #? - PullRequest
       6

_BitScanForward в C #?

6 голосов
/ 01 февраля 2012

Я перевожу программу, написанную на C ++, на C # и натолкнулся на встроенную функцию, которую я не могу обойти.В C ++ это известно как:

unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask);

Если бы я знал только, в какой DLL, если таковые имеются, встроенные функции, я мог бы использовать P / Invoke.Поскольку я не знаю, я искал альтернативы в .NET Framework, но я пришел с пустыми руками.

Кто-нибудь знает, как использовать P / Invoke на _BitScanForward или метод .NET, который делает то же самоевещь?

Любая помощь приветствуется, спасибо.

Ответы [ 4 ]

6 голосов
/ 01 февраля 2012

Встроенные функции отсутствуют в какой-либо библиотеке, они реализованы внутри ЦП, компилятор выдает машинный код , который ЦП распознает как вызывающий это конкретное поведение.

Это способ получить доступ к инструкциям, которые не имеют простого эквивалента C.

Пока оптимизатор .NET не станет достаточно умным, чтобы распознавать их (например, Mono JIT распознает некоторые SIMD-инструкции, закодированные в MSIL, как вызовы функций определенного класса, аналогично .NET JIT заменяет вызовы методов System.Math. с операциями с плавающей запятой), ваш код C # обречен работать на порядок медленнее, чем исходный C ++.

3 голосов
/ 01 февраля 2012

_BitScanForward выполняет поиск первого установленного бита в целом числе, начиная с поиска младшего значащего бита в направлении старшего значащего бита. Он компилируется в инструкцию bsf на платформе x86.

На странице «Хитрые трюки» содержится несколько потенциальных алгоритмов замены, которые превосходны в различных ситуациях. Есть функция O (N) (которая половину времени с равномерно распределенными входами возвращает только с одной итерацией) и некоторые сублинейные опции, а некоторые используют шаги умножения. Выбор одного не может быть тривиальным , но любой должен работать.

3 голосов
/ 01 февраля 2012

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

2 голосов
/ 01 февраля 2012

P / Invoke _BitScanForward не представляется возможным, потому что это встроенная функция компилятора, а не фактическая библиотечная функция (она переводится компилятором Visual C ++ в машинную инструкцию BSF x86). Насколько я знаю, нет инструкции MSIL для этой операции "найти первый набор". Самое простое, что нужно сделать - это написать собственную собственную C ++ DLL, которая экспортирует функцию, которая вызывает _BitScanForward (), а затем P / Invoke, что.

Вы также можете написать его непосредственно в C #, используя битовые манипуляции (см. Алгоритмы для поиска первого набора в Википедии ). Я не уверен, будет ли это быстрее или медленнее, чем P / Invoke. Измерь и узнай.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...