недопустимая команда сдвига битов только в 64-битном режиме

Я интегрирую доступный код PoissonRecon Вот в мой собственный код манипулирования сеткой, но я не смог скомпилировать интегрированный код в x64 из-за ошибки «недопустимая команда» в каждой команде сдвига битов при генерации октр кода Пуассона.

Я использую Visual Studio 2015, и моя проблема возникает только при компиляции в x64 и только в режиме релиза (то есть, он работает в отладке и выпуске x86, а также в отладке x64).

В качестве примера одной из инструкций сдвига битов в верхней части файла Octree.inl определено следующее:

template< class NodeData > const int OctNode< NodeData >::DepthShift=5;
template< class NodeData > const int OctNode< NodeData >::OffsetShift = ( sizeof(long long)*8 - DepthShift ) / 3;
template< class NodeData > const int OctNode< NodeData >::DepthMask=(1<<DepthShift)-1; // This variable is correct
template< class NodeData > const int OctNode< NodeData >::OffsetMask=(1<<OffsetShift)-1; // This variable is also correct
template< class NodeData > const int OctNode< NodeData >::OffsetShift1=DepthShift;
template< class NodeData > const int OctNode< NodeData >::OffsetShift2=OffsetShift1+OffsetShift;
template< class NodeData > const int OctNode< NodeData >::OffsetShift3=OffsetShift2+OffsetShift;

И эти переменные используются в следующей функции:

template< class NodeData >
inline unsigned long long OctNode< NodeData >::Index( int depth , const int offset[3] )
{
unsigned long long idx=0;
idx |= ( ( (unsigned long long)(depth    ) ) & DepthMask  );
idx |= ( ( (unsigned long long)(offset[0]) ) & OffsetMask ) << OffsetShift1;
idx |= ( ( (unsigned long long)(offset[1]) ) & OffsetMask ) << OffsetShift2;
idx |= ( ( (unsigned long long)(offset[2]) ) & OffsetMask ) << OffsetShift3;
return idx;
}

Эта функция разрывается на линии

idx |= ( ( (unsigned long long)(offset[0]) ) & OffsetMask ) << OffsetShift1;

который я разделил далее и обнаружил, что проблема заключается в самом сдвиге битов, т.е. (var)<<OffsetShift1; но это вызывает ошибку «недопустимая инструкция».

Обратите внимание, что OffsetShift1 просто «5», так что это эквивалентно (var)<<5; который работает как ожидалось.

Возможный обходной путь — просто #define все эти переменные сверху (что решает проблему), но это не решает другие проблемы сдвига битов, такие как следующие:

void _startAndWidth( const TreeOctNode* node , Point3D< Real >& start , Real& width ) const
{
LocalDepth d ; LocalOffset off;
_localDepthAndOffset( node , d , off );
if (d >= 0) width = Real(1.0 / (1 << d));
else width = Real( 1.0 * (1<<(-d)) );
for( int dd=0 ; dd<DIMENSION ; dd++ ) start[dd] = Real( off[dd] ) * width;
}

Я пытался static_cast<long long> все, но это не проблема переполнения. Даже более странно, если я прерваюсь перед сдвигом битов (находясь в режиме освобождения) и затем выделю операцию, отладчик сообщит мне правильный результат (например, d = 5 в _startAndWidth, так 1 << d возвращает 32 в отладчике), но на самом деле перешагнуть через операцию вызывает ошибку «недопустимая инструкция».

Так как программа работает правильно в режиме отладки, я попытался удалить все оптимизации в режиме выпуска, но я все еще получаю ту же ошибку. Единственный обходной путь, который я нашел, — это заменить все операции сдвига битов pow() вместо этого, и пока это работает, кажется, bit смешной.

2

Решение

Оказывается, файл .sln, который поставляется с кодом восстановления, был установлен с помощью AVX2, который не был поддержан на моем компьютере.

собирается Configuration Properties >> C/C++ >> Code Generation и установка «Включить расширенный набор инструкций» в AVX решила проблему.

Код сборки теперь показывает «SHL» вместо «SHLX», поэтому «недопустимая инструкция» заключалась в том, что фактическая команда SHLX была недоступна, а не проблема с параметрами, входящими в SHLX.

1

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

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

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