Преобразование встроенного ASM в встроенный для x64 igraph

Я компилирую из исходного кода расширение Python IGRAPH для x64 вместо x86, которое доступно в дистрибутиве. Я получил все это в VS 2012, и он компилируется, когда я комментирую в src / math.c следующим образом

#ifndef HAVE_LOGBL
long double igraph_logbl(long double x) {
long double res;
/**#if defined(_MSC_VER)
__asm { fld [x] }
__asm { fxtract }
__asm { fstp st }
__asm { fistp [res] }
#else
__asm__ ("fxtract\n\t""fstp  %%st" : "=t" (res) : "0" (x));
#endif*/
return res;
}
#endif

Проблема в том, что я плохо знаю asm и знаю недостаточно хорошо, чтобы знать, есть ли проблемы, переходящие с x86 на x64. Это короткий фрагмент из 4 сборочных инструкций, которые, как я вижу, должны быть преобразованы в внутренние компоненты x64.

Есть указатели? Идет ли внутренне правильный путь? Или это должна быть подпрограмма или чистый C?

Изменить: Ссылка на расширение igraph, если кто-то хотел увидеть http://igraph.sourceforge.net/download.html

3

Решение

В x64 с плавающей точкой, как правило, будут выполняться с использованием инструкций SSE2, поскольку они, как правило, намного быстрее. Ваша единственная проблема здесь в том, что в SSE нет эквивалента операции fxtract (что обычно означает, что версия FPU будет реализована как составная инструкция и, следовательно, будет очень медленной). Таким образом, реализация в виде функции на C, скорее всего, будет такой же быстрой на x64.

Однако я нахожу эту функцию немного трудной для чтения, поскольку из того, что я могу сказать, она вызывает fxtract, а затем сохраняет целочисленное значение по адресу, указанному в длинном double. Это означает, что long double будет иметь «частично» неопределенное значение. Как я могу сказать, приведенная выше сборка кода не должна работать … но это ОЧЕНЬ долгое время с тех пор, как я написал любой код x87, так что я, вероятно, просто ржавый.

В любом случае, функция, кажется, является реализацией logb который вы не найдете реализованным в MSVC. Однако его можно реализовать следующим образом с помощью функции frexp:

long double igraph_logbl(long double x)
{
int exp = 0;
frexpl( x, &exp );
return (long double)exp;
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]