Есть ли в MSIL инструкции по ROL и ROR? - PullRequest
4 голосов
/ 10 июля 2010

Я написал тип Int128, и он прекрасно работает.Я подумал, что могу улучшить его производительность с помощью простой идеи: улучшить операции сдвига, которые немного неуклюжи.

Поскольку они интенсивно используются при умножении и делении, улучшение будет иметь волновой эффект.Поэтому я начал создавать динамический метод (сдвиг низкого и поворот высокого) только для того, чтобы обнаружить, что в нем нет инструкций OpCodes.Rol или OpCodes.Ror.

Возможно ли это в IL?

Ответы [ 2 ]

4 голосов
/ 10 июля 2010

Нет.

Вам нужно реализовать это с битовыми сдвигами

UInt64 highBits = 0;
UInt64 lowBits = 1;
Int32 n = 63;
var altShift = (n - 63);

var lowShiftedOff = (n - 63) > 0 ? 0 : (lowBits << n);
var highShiftedOff = (n - 63) > 0 ? 0 : (highBits << n);

var highResult = (UInt64)(highShiftedOff | (altShift > 0 ? (lowBits << altShift - 1) : 0));
var lowResult= (UInt64)(lowShiftedOff | (altShift > 0 ? (highBits << altShift - 1) : 0));
2 голосов
/ 21 декабря 2017

Чтобы частично ответить на этот вопрос 7 лет спустя, на тот случай, если кому-то это понадобится.

Вы можете использовать ROR / ROL в .Net.

MSIL напрямую не содержит ROR или ROLопераций, но есть шаблоны, которые заставят JIT-компилятор генерировать ROR и ROL.RuyJIT (ядро .Net и .Net) поддерживает это.

Подробности улучшения .Net Core для использования этого шаблона обсуждались здесь , а месяцем позже .Net Core был обновлен, чтобы использовать его .

Рассматривая реализацию SHA512 , мы находим примеры ROR:

    public static UInt64 RotateRight(UInt64 x, int n) {
        return (((x) >> (n)) | ((x) << (64-(n))));
    }

И расширяем по той же схеме до ROL:

    public static UInt64 RotateLeft(UInt64 x, int n) {
        return (((x) << (n)) | ((x) >> (64-(n))));
    }

Чтобы сделать это для 128-разрядного целого числа, вы можете обработать как два 64-разрядных, затем AND для извлечения «переноса», AND для очистки места назначения и OR для применения.Это должно быть отражено в обоих направлениях (низкий-> высокий и высокий-> низкий).Я не собираюсь возиться с примером, так как этот вопрос немного стар.

...