2009-09-19 8 views
1

이 코드를 Mac에서 작동하는 어셈블리 코드로 변경하려면 어떻게해야합니까?이 코드를 어셈블리 코드로 작성하는 방법은 무엇입니까?

while (a --) 
{ 
    *pDest ++ += *pSrC++; 
} 
+2

왜 이것을 원합니까? 컴파일러가이 블록에 최적화 된 코드를 생성하지 않는다는 증거가 있습니까? –

+1

Intel Mac 또는 PPC (what gen)? 나는 어셈블리를 모르지만 x86과 PPC 어셈블리가 다를 것이라는 것을 충분히 알고 있습니다. – UnkwnTech

+1

그것은 intel mac과 iPhone에 있습니다. 스레드에서이 코드를 사용하는 프로그램에서 작업 중이며 스레드는 항상 그런 물건을 다루고 있습니다. 때로는 멈추었 기 때문에 계산이 iPhone에 너무 무거울 지 궁금합니다. – Yuhui

답변

2

이것은 팔을위한 것입니까? (아이폰?).이 포인터 (바이트, 하프 워드, 단어 등)의 크기는 정렬 문제가 있습니까 (단어가 아닌 경계에서 단어 복사)? 만약 이들이 바이트라면, 생성 된 코드는 고통스럽게 속도가 느릴 것이며, 옵티마이 저가 너무 많은 것을 할 수 없습니다. 그게 당신을 어디로 떠나요? 당신은 당신이 얻는 것을 얻습니다. 여기

은 예입니다 코드가 계산 포인터를 가지고 있기 때문에, 컴파일러는 명령이 didnt 한 필요를 추가
mov ip, #0 
.L3: 
    ldrb r3, [r0, ip] @ zero_extendqisi2 
    ldrb r2, [r1, ip] @ zero_extendqisi2 
    add r3, r3, r2 
    strb r3, [r1, ip] 
    add ip, ip, #1 
    cmp ip, r4 
    bne .L3 

. 캐리 비트가 나는 기반으로 단어를 단어를로드 할 수있는 방법이 있는지 궁금 사용되지 않기 때문에

sub  ip, rx, #1 
.L3: 
    ldrb r3, [r0, ip] @ zero_extendqisi2 
    ldrb r2, [r1, ip] @ zero_extendqisi2 
    add r3, r3, r2 
    strb r3, [r1, ip] 
    subs ip, ip, #1 
    bne .L3 

한 번에 하나 개의 단어를하고, 추가합니다.

load 0xnnmmoopp 
load oxqqrrsstt 

0xnnmmoopp

더 캐리 문제를 보장 할 그들 중 하나를 마스크 -> 0xn0mmo0pp

추가

0xgghhiikk = 0xn0mmo0pp 0xqqrrsstt

는 바이트

로 HH 및 KK를 저장 +

원본으로 돌아 가야합니다. inal cripple mm 및 pp 바이트가 gg 및 ii 바이트를 다시 추가하고 저장합니다.

위의 내용을 모두 레지스터에 저장하고 4 바이트 저장소 대신 워드 저장소를 사용하면 상당히 많은 시간을 절약 할 수 있지만 두 단어 읽기는 4 바이트 읽기보다 훨씬 빠릅니다.

많은 레지스터를 스택에 저장해야하므로 비용이 적게 드는 것이므로 작은 값 (10 개 미만)에 대해서는이 작업을 수행하지 마십시오.

어쨌든, 생각해 볼만한 것이 있습니다. 위의 asm에서 한 줄의 코드를 제거하면 장기 실행에 눈에 띄게됩니다.

편집 :

는 사실 내가 컴파일러 출력에 행한 수정이 부서졌다. 이것은 다음과 같습니다 :

mov ip, ra 
.L3: 
    subs ip, ip, #1 
    ldrb r3, [r0, ip] 
    ldrb r2, [r1, ip] 
    add r3, r3, r2 
    strb r3, [r1, ip] 
    bne .L3 
+0

고마워, 나는 여기있는 모든 사람들에게 감사하고, 나는 당신에게서 많은 것을 배웁니다. – Yuhui

2

실제 어셈블러 명령어는 다를 수 있지만 여기 어셈블러로 쉽게 변환 할 수있는 의사 코드가 있습니다.

참고로 * 4는 int를 전송한다고 가정하기 때문입니다. 그것은 전송되는 데이터의 크기에 따라 달라질 것입니다.

incrementor = 0 ;really easy 
top: 
jump to bottom if a equals 0  ;jump if zero is the intel instruction here. 
memoryDest[incrementor*4] = memorySrc[incrementor*4] ;this will be a bit messy, you'll probably need some temp variables 
incrementor += 1 ;dead easy 
jump to top: ;goto. PLEASE DON'T CITE 'CONSIDERED HARMFUL`, THIS IS ASM!!!!11ONEONE 
bottom: 
+0

고마워요,하지만 GNU 어셈블리 코드로 변환 할 수 있습니까?나는 그것에 익숙하지 않다. – Yuhui

+2

@Yuhui, 자신의 프로젝트에 자신의 노력을 기꺼이 사용하지 않는다면, 나는 당신의 프로젝트에 대해 내 노력을 기꺼이 사용하지 않을 것이다. 적어도 * 시도해 봤어? – strager

+0

그래, 노력하고 시작하는 법을 모르겠다. 조립 경험이 없으니 정말 유감입니다 ... – Yuhui

0

iPhone 용으로 개발 중이며 속도를 높이려고한다고합니다. memcpy(dest, src, size)을 사용하려는 메모리 블록을 복사하려고하는 것 같습니다.

+0

죄송합니다. 원하는 것은 * pDest ++ + = * pSrc입니다. 이전에 잘못된 붙여 넣기를했습니다. 이렇게하려면 더 빨리 만들 수있는 아이디어가 있습니까? – Yuhui

+1

아니요, 가지고있는 코드가 가장 빠릅니다. 배열이 거대하지 않으면 병목 현상이 발생하지 않을 가능성이 있습니다. 문제에 대해 좀 더 많은 정보를 제공하면 도움이 될 것입니다. –

6

아이폰과 아이폰에 있습니다. 스레드에서이 코드를 사용하는 프로그램에서 작업하고 스레드가 항상 그런 물건을하고 때로는 붙어있어 그래서 계산이 iPhone에 너무 무겁 냐고 궁금해합니다.

아니요, 문제는이 코드와 아무 관련이 없습니다. 컴파일러가 그 일을하고 최적화하도록하십시오. 너의 문제는 다른 곳에있다. 어떻게 든간에 스레드간에 경쟁 조건이나 교착 상태가있는 것 같습니다. 더 많은 정보가 없으면 정신적으로 문제를 디버깅 할 수는 없지만 잘못된 트리를 짖고 있다고 말할 수 있습니다.

2

해당 배열이 적당한 길이이고 pDest 및 pSrc의 유형에 따라 ARMv7 (iPhone 3GS)의 새로운 NEON 명령어를 사용하여 합리적인 속도 향상을 얻을 수 있습니다 터치) 및 Intel에서 SSE를 사용합니다.

특정 코드와 속도 향상 속도는 소스 및 대상 배열의 데이터 유형, 배열 주소에 대한 정렬을 보장하며, 배열은 같다.

항상 그렇듯이이 루프가 실행 시간의 상당한 부분을 차지하는 상어 추적을하지 않는 한 아무 것도 할 가치가 없습니다. Mac 또는 iPhone에서 응용 프로그램 수준의 성능 튜닝을 수행하고 Shark 또는 Instruments를 사용하지 않는 경우 문제가 발생합니다.

배열이 부동 소수점 인 경우 Accelerate.framework를 포함하고 vDSP_vadd() 함수를 사용하면 Intel Mac에서 잘 조정 된 벡터 코드를 얻을 수 있습니다. 어셈블리 코딩이 필요하지 않습니다.

는 2008 년 WWDC 회담에 액세스 할 수있는 경우

는 에릭 Postpischil 정확히 경우이 루프 (PSRC와 pDest는 단일 곳 을 처리하기 위해 그가 쓰는 벡터 코드를 통해 걸어하는 기본 벡터화 기법에 좋은 이야기를했다 정밀 배열)을 사용했지만 단순하게 ASM 대신 벡터 내장 함수를 사용하여 C를 사용했습니다.

1

약간의 stackshots이 실제로 여기에 머무르는 시간 인 경우 표시됩니다.

이 같이 도울 수있는 루프를 줄이기, 경우 :

while (a >= 8){ 
    pDest[0] += pSrc[0]; 
    pDest[1] += pSrc[1]; 
    pDest[2] += pSrc[2]; 
    pDest[3] += pSrc[3]; 
    pDest[4] += pSrc[4]; 
    pDest[5] += pSrc[5]; 
    pDest[6] += pSrc[6]; 
    pDest[7] += pSrc[7]; 
    pDest += 8; 
    pSrc += 8; 
    a -= 8; 
} 
// followed by your loop 

당신은 어셈블러에서 코딩 할 수 있지만 아마 훨씬 더 없을 것이다.

관련 문제