이 코드를 Mac에서 작동하는 어셈블리 코드로 변경하려면 어떻게해야합니까?이 코드를 어셈블리 코드로 작성하는 방법은 무엇입니까?
while (a --)
{
*pDest ++ += *pSrC++;
}
이 코드를 Mac에서 작동하는 어셈블리 코드로 변경하려면 어떻게해야합니까?이 코드를 어셈블리 코드로 작성하는 방법은 무엇입니까?
while (a --)
{
*pDest ++ += *pSrC++;
}
이것은 팔을위한 것입니까? (아이폰?).이 포인터 (바이트, 하프 워드, 단어 등)의 크기는 정렬 문제가 있습니까 (단어가 아닌 경계에서 단어 복사)? 만약 이들이 바이트라면, 생성 된 코드는 고통스럽게 속도가 느릴 것이며, 옵티마이 저가 너무 많은 것을 할 수 없습니다. 그게 당신을 어디로 떠나요? 당신은 당신이 얻는 것을 얻습니다. 여기
은 예입니다 코드가 계산 포인터를 가지고 있기 때문에, 컴파일러는 명령이 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
고마워, 나는 여기있는 모든 사람들에게 감사하고, 나는 당신에게서 많은 것을 배웁니다. – Yuhui
실제 어셈블러 명령어는 다를 수 있지만 여기 어셈블러로 쉽게 변환 할 수있는 의사 코드가 있습니다.
참고로 * 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:
iPhone 용으로 개발 중이며 속도를 높이려고한다고합니다. memcpy(dest, src, size)을 사용하려는 메모리 블록을 복사하려고하는 것 같습니다.
죄송합니다. 원하는 것은 * pDest ++ + = * pSrc입니다. 이전에 잘못된 붙여 넣기를했습니다. 이렇게하려면 더 빨리 만들 수있는 아이디어가 있습니까? – Yuhui
아니요, 가지고있는 코드가 가장 빠릅니다. 배열이 거대하지 않으면 병목 현상이 발생하지 않을 가능성이 있습니다. 문제에 대해 좀 더 많은 정보를 제공하면 도움이 될 것입니다. –
아이폰과 아이폰에 있습니다. 스레드에서이 코드를 사용하는 프로그램에서 작업하고 스레드가 항상 그런 물건을하고 때로는 붙어있어 그래서 계산이 iPhone에 너무 무겁 냐고 궁금해합니다.
아니요, 문제는이 코드와 아무 관련이 없습니다. 컴파일러가 그 일을하고 최적화하도록하십시오. 너의 문제는 다른 곳에있다. 어떻게 든간에 스레드간에 경쟁 조건이나 교착 상태가있는 것 같습니다. 더 많은 정보가 없으면 정신적으로 문제를 디버깅 할 수는 없지만 잘못된 트리를 짖고 있다고 말할 수 있습니다.
해당 배열이 적당한 길이이고 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를 사용했습니다.약간의 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
당신은 어셈블러에서 코딩 할 수 있지만 아마 훨씬 더 없을 것이다.
왜 이것을 원합니까? 컴파일러가이 블록에 최적화 된 코드를 생성하지 않는다는 증거가 있습니까? –
Intel Mac 또는 PPC (what gen)? 나는 어셈블리를 모르지만 x86과 PPC 어셈블리가 다를 것이라는 것을 충분히 알고 있습니다. – UnkwnTech
그것은 intel mac과 iPhone에 있습니다. 스레드에서이 코드를 사용하는 프로그램에서 작업 중이며 스레드는 항상 그런 물건을 다루고 있습니다. 때로는 멈추었 기 때문에 계산이 iPhone에 너무 무거울 지 궁금합니다. – Yuhui