我写了一个Int128类型,它很好用。我认为可以通过一个简单的想法来提高其性能:改进有点笨拙的移位操作。
因为移位操作在乘法和除法中被广泛使用,所以一次改进会产生连锁反应。因此,我开始创建一个动态方法(用于低位移位和高位旋转),只发现没有OpCodes.Rol或OpCodes.Ror指令。
在IL中是否可能实现这一点?
我写了一个Int128类型,它很好用。我认为可以通过一个简单的想法来提高其性能:改进有点笨拙的移位操作。
因为移位操作在乘法和除法中被广泛使用,所以一次改进会产生连锁反应。因此,我开始创建一个动态方法(用于低位移位和高位旋转),只发现没有OpCodes.Rol或OpCodes.Ror指令。
在IL中是否可能实现这一点?
不需要。
您需要使用位移运算符实现它。
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));
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))));
}
public T RotateLeft<T>(T val, int n) { var bits = Marshal.SizeOf(val) * 8; n %= bits; return ((val << (n) | (val >> (bits - n))); /* ?? */ }
) - EcnelisMarshal.SizeOf()
(Windows API调用,如果我没记错的话)而不是sizeof()
(编译时常量)将抵消任何潜在ROL/ROR的性能优势。因此,即使您编译了正确的代码,也不会有任何好处。 - Tedd Hansen