2010-07-10 3 views
4

필자는 Int128 유형을 작성했으며 훌륭하게 작동합니다. 나는 간단한 아이디어로 그것의 성능을 향상시킬 수 있다고 생각했다. 조금 어색한 교대 조작을 개선하라.MSIL에 ROL 및 ROR 명령어가 있습니까?

그들은 곱셈과 나눗셈에 많이 사용되기 때문에 리플 효과가 향상됩니다. 그래서 동적 인 방법을 만들고 (낮은쪽으로 이동하고 높은쪽으로 돌리기), OpCodes.Rol 또는 OpCodes.Ror 지침이 없다는 것을 발견하기 시작했습니다.

IL에서 가능한가요?

+0

비트 순환을위한 CIL 연산 코드가 없더라도 JIT 컴파일러는 여전히 여러 CIL 연산 코드를 기본 시스템의 명령어 세트에있는 ROL 및 ROR 명령어에 매핑 할만큼 똑똑 할 수 있습니다. (실제로 JIT 컴파일러가 똑똑하다고 생각하지 않지만 적어도 가능합니다.) 나는 말하고 싶다 : 나는 너무 많이 걱정하지 않을 것이다. 실제 어셈블리 언어에 비해 CIL 코드는 매우 비효율적 인 것처럼 보이지만 JIT 컴파일러는이를 다소 완화 할 것입니다. – stakx

답변

4

당신은 비트와 함께 구현해야

번호

사례 누군가가 그것을 필요로한다에

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)); 
+1

감사합니다. 내가 두려워했던 것을 확인했다. .NET 4.0의 BigInteger에서 그들이 어떻게했는지 보았습니다. 이제는 제 생각이 나쁘다고 생각하지 않습니다. – Tergiver

+1

SHL과 SHR은 shift 피연산자의 마지막 5 개 (U/Int32의 경우) 또는 6 (U/Int64의 경우) 비트 만보고 전체 시프트 값에 대한 모듈러스를 효과적으로 생성한다는 사실을 간과했습니다. . 이것은 비트를 이동하려고 할 때 큰 고통이며, 왜 이렇게 구현되었는지 이해할 수 없습니다. – codekaizen

+0

시프트 피연산자는 관련 유형의 크기보다 작은 시프트에 대해서만 정의됩니다. * n * 비트 유형에 대해 * n * 비트 이상을 시프트하는 것이별로 의미가 없기 때문입니다. 표준 (ECMA 335 : §3.59)은 ''shiftAmount '가'value '의 너비보다 크거나 같으면 반환 값이 지정되지 않습니다.' – porges

0

부분적으로 7 년 후에이 질문에 대답하기 위해 이동합니다.

.Net에서 ROR/ROL을 사용할 수 있습니다.

MSIL에는 ROR 또는 ROL 연산이 직접 포함되지 않지만 JIT 컴파일러에서 ROR 및 ROL을 생성하는 패턴이 있습니다. RuyJIT (.Net 및 .Net 코어)는이를 지원합니다.

이 패턴을 사용하기위한 .Net Core의 개선 내용은 discussed here이며 1 개월 후 .Net Core code는 updated to use it입니다.

우리가 ROR의 예를 찾아 implementation of SHA512에서 상대 :

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를 사용하여 "캐리"를 추출하고 대상을 지우고 OR을 적용합니다. 이것은 양방향으로 미러링되어야합니다 (낮음 - 높음 및 높음 - 낮음). 나는이 질문이 약간 낡았 기 때문에 예제로 귀찮게하지 않을 것이다.