2014-01-08 1 views
2

GF (2^n)의 요소 인 두 다항식을 곱하기 위해 C 코드에서 인라인 어셈블리와 함께 인텔의 PCLMULQDQ 명령어를 사용하고 싶습니다. 컴파일러는 GCC 4.8.1입니다. 다항식은 uint32_t의 배열에 저장됩니다 (6 개의 큰 필드).C 인라인 asm의 PCLMULQDQ 명령어

PCLMULQDQ 명령어 또는 CLMUL 명령어 사용법을 웹에서 이미 확인했지만 올바른 문서를 찾지 못했습니다.

두 개의 간단한 다항식에 명령을 곱하는 방법에 대한 C와 asm의 간단한 예제를 고맙게 생각합니다. 아무도 그것을하는 방법을 알고 있습니까?

게다가 포함 된 라이브러리, 컴파일러 옵션 등과 같이 모든 필수 구성 요소 (가능한 프로세서 제외)가 있습니까?

+0

빠른 검색 결과 http://download-software.intel.com/sites/default/files/article/165685/clmul-wp-rev-2.01-2012-09-21.pdf –

답변

0

이미 해결책을 찾았습니다. 따라서 기록을 위해 :

void f2m_intel_mult(
    uint32_t t, // length of arrays A and B 
    uint32_t *A, 
    uint32_t *B, 
    uint32_t *C 
) 
{ 
    memset(C, 0, 2*t*sizeof(uint32_t)); 
    uint32_t offset = 0; 
    union{ uint64_t val; struct{uint32_t low; uint32_t high;} halfs;} prod; 

    uint32_t i; 
    uint32_t j; 
    for(i=0; i<t; i++){ 
     for(j=0; j<t; j++){ 

      prod.halfs.low = A[i]; 
      prod.halfs.high = 0; 
      asm ("pclmulqdq %2, %1, %0;" 
      : "+x"(prod.val) 
      : "x"(B[j]), "i"(offset) 
      ); 

      C[i+j] = C[i+j]^prod.halfs.low; 
      C[i+j+1] = C[i+j+1]^prod.halfs.high; 
     } 
    } 
} 

나는 pclmulqdq에 대한 64 비트 레지스터를 사용하는 것이 가능하다고 생각하지만, 나는 이것이 인라인 어셈블러와 함께 작업을 진행하는 방법을 찾을 수 없습니다. 아무도 이걸 압니까?
그럼에도 불구하고 내장 함수를 사용하여 동일한 작업을 수행 할 수도 있습니다. (코드에서 묻기를 원할 경우)
배열의 크기를 알면 Karatsuba로 계산을 최적화하는 것이 더할 수 있습니다.

+0

[컴파일러 출력 이] (https://godbolt.org/g/eaQrRx)은 여러면에서 끔찍합니다. 먼저, 모든 pclmul은 64 비트 정수 레지스터를 xmm 레지스터의 하위 절반에 복사하는 'movq'로 둘러싸여 있습니다. 두 번째로, 'xor' 연산은 64 비트 xor 또는 메모리 대상과 병합하는 대신 32 비트 피연산자 크기를 사용합니다. –

+0

아니요, integer/gp 레지스터 [xmm] (http://www.felixcloutier.com/x86/PCLMULQDQ.html)에서만 작동하는 pclmul의 형식은 없습니다. 128 비트의 데이터를 SSE 벡터에 직접로드하고 다른 즉시 오프셋을 갖는'pclmul'을 사용하여 곱셈의 다른 부분을 수행하는 것이 훨씬 더 효율적입니다. 'A'를 64 비트 요소로 제로 확장해야한다면 SSE에서 'punpckldq'로 레지스터를 0으로 할 수 있습니다. (또는 SSE4.1'pmovzx'). 실제로 B에 대해서도 똑같은 일을하고 있지만 암묵적으로 말입니다. –

+0

SSE 연산을 사용하여 XOR을 'C'로 처리해야합니다. (C에서로드,'pxor', 다시 저장하십시오.) 어쨌든, 반드시 인라인 asm이 아닌 intrinsics로 이것을 수행해야합니다. 인라인 ASM은 정확하고 안전하지만 많은 성능을 잃어 가고 있습니다. –