Есть ли у MSIL инструкции ROL и ROR?
Я написал тип Int128, и он отлично работает. Я думал, что смогу улучшить его производительность с помощью простой идеи: улучшить операции смены, которые немного неуклюжи.
Поскольку они широко используются при умножении и делении, улучшение будет иметь волновой эффект. Поэтому я начал создавать динамический метод (сдвигать вниз и поворачивать вверх), только чтобы обнаружить, что нет никаких опкодов.Рол или опкоды.Инструкции Рора.
Возможно ли это в IL?
2 ответа:
Нет.
Вам нужно реализовать его с помощью битовых сдвигов
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));
Частично ответить на этот вопрос 7 лет спустя, на случай, если кому-то это понадобится.
Вы можете использовать ROR/ROL в. Net.
MSIL напрямую не содержит операций ROR или ROL, но существуют шаблоны, которые заставят компилятор JIT генерировать ROR и ROL. RuyJIT (.Net и .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-битных, затем и извлечь "carry", и очистить destination и или применить. Это должно быть отражено в обоих направлениях (низкий->высокий и высокий->низкий). Я не собираюсь утруждать себя примером, поскольку этот вопрос немного устарел.