2016-12-19 5 views
-2

저는 어셈블리가 매우 새롭고 1에서 100까지의 범위에서 모든 pythagorean 트리플을 찾고 싶습니다. C로 모든 숫자를 생성하고 있으며 다른 모든 계산은 어셈블리 SSE에서 수행해야합니다. sqrt 명령을 사용하여이 작업을 수행하려고했으나 (모두 시도했지만) 작동하지 못했습니다. 누군가 어떻게 수행해야하는지 알려 줄 수 있습니까?SSE 조립 지침을 사용하여 pythagorean 트리플을 찾는 방법은 무엇입니까?

int main(){ 
      for (int i = 1; i <= 100; i++) 
      { 
       a++; 
       if (a > 100) 
        a = 0; 
       for (int j = 1; j <= 100; j++) 
       { 
        b++; 
        if (b > 100) 
         b = a; 
        _asm //tricky part begins here: 
        { 
         movups xmm0, a 
         movups xmm1, b 
         pmuludq xmm0, xmm0 
         pmuludq xmm1, xmm1 
         //movups xmm2, 0 
         //paddd xmm2, xmm0 
         //paddd xmm2, xmm1 
         movups z, xmm0 
        } 
        printf("%d\n", z); 
       } 
      } 
    } 
+7

"C보다 빠르기 때문에 어셈블리에서이 작업을 수행하고 싶습니다." 어떻게 알았어? 아마 그렇지 않을 것이기 때문입니다. –

+6

필자의 손으로 작성한 asm은 C 컴파일러 출력보다 빠르다고 가정하지 않습니다. 컴파일러는 똑똑하고 현대적인 CPU는 복잡합니다. – Blorgbeard

+0

알고리즘을 C 또는 의사 코드로 먼저 적어 둡니다. – Jester

답변

2

당신의 접근 방식에 근본적인 문제는 그냥 C에서로드 할 수 있도록 병렬로 4 개 b 값을보고 할 필요가있다 : 내가 지금까지있어 무엇

스칼라 변수. 메모리 또는 무언가로부터 벡터를 로딩하는 것이 아니라 루프 반복을 통해 벡터 레지스터에 물건을 보관해야합니다. MSVC 인라인 asm은 짧은 시퀀스를 래핑하는 것을 피하기 때문에 asm으로 전체 루프를 작성해야합니다. 결과를 얻는 데 피할 수없는 오버 헤드가 있기 때문입니다.

물론이 루프를 벡터화하는 가장 좋은 방법은 인라인 asm이 아닌 C 내장 함수를 사용하는 것입니다. 그런 다음 비효율적 인 asm 출력을 검사하여 필요한 경우 (그리고 가능한 경우)보다 나은 asm을 만들기 위해 컴파일러를 손으로 잡을 수 있습니다. 당신이 정말 피타고라스는 트리플 생성하는 효율적인 코드를 생성하기를 원한다면, 너무 알고리즘은 가짜입니다, 물론


(Why is this C++ code faster than my hand-written assembly for testing the Collatz conjecture? 참조) :

위키 백과의 문서는 유클리드의 공식을 설명하는 generating a triple 섹션이 . 그 반복은 숫자가 완벽한 사각형인지를 검사하는 것이 상당히 느리기 때문에 a=[1..100] b=[1..100] 검색 공간 전체에 대한 무차별 강제 검색에서 히트를 확인하는 것보다 다른 문제가 될 수 있습니다.

또한 어떤 벡터 요소가 조건과 일치하는지 탐지하는 것은 어색합니다. 압축 비교 명령과 PMOVMSKB (또는 MOVMSKPS)는 비트 맵을 제공하지만 히트가 드문 경우 (예 : memchr을 구현하면 루프가 처음으로 중단 된 후 중지됩니다.

+0

평균 데스크톱 컴퓨터에서'a = [1..100] b = [1..100]'검색 공간 전체를 검사하는 데 걸리는 시간이 0.005 초 미만이므로 질문의 전체 전제가 어리석은 점에 유의하십시오. – user3386109

+0

@ user3386109 : 성능 카운터로 정확하게 측정 할 수있을만큼 충분히 긴 백만 또는 2 코어 클럭 사이클입니다. 그러나 명백하게 요점은 더 큰 검색 범위에 더 많이 적용됩니다. 그리고 각 히트에서 검색의 중간에'printf'를 호출하는 것은 어리석은 일입니다. –