如何使用汇编代码编写此代码?

时间:2009-09-19 03:17:36

标签: macos assembly

我想将此代码更改为汇编代码,在mac上工作,如何执行此操作?

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

6 个答案:

答案 0 :(得分:6)

  

这是intel mac,在iPhone上。我正在研究一个在线程中使用此代码的程序,并且线程总是在做这样的事情,有时它会卡住,所以我想知道是不是因为iPhone的计算太重了。

不,您的问题与此代码无关。让编译器完成它的工作并优化它。你的问题在别处。听起来你在某种程度上有一个竞争条件或线程之间的死锁。在没有更多信息的情况下,我无法在心理上调试你的问题,但我可以肯定地说你正在咆哮错误的树。

答案 1 :(得分:2)

实际的汇编程序指令会有所不同,但这里的伪代码可以很容易地转换为汇编程序。

请注意* 4是因为我假设您正在转移。它将根据传输的数据大小而有所不同。

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:

答案 2 :(得分:2)

假设所讨论的阵列长度合理,并且取决于pDest和pSrc的类型,您可以通过使用ARMv7上的NEON指令(iPhone 3GS和新的Touch)来获得合理的加速),并在英特尔上使用SSE。

具体的代码,以及你可以获得多少加速,将取决于源和目标数组中的数据类型,对数组地址的保证,以及典型长度的分布。数组就像。

与往常一样,除非你有一个Shark跟踪显示这个循环是你执行时间的可观部分,否则这一切都不值得做。如果你在Mac或iPhone上进行应用程序级性能调整而你没有使用Shark或Instruments,那你就错了。

如果阵列是浮点数,您可以通过包含Accelerate.framework和使用vDSP_vadd()函数在Intel mac上获得经过良好调整的矢量代码。无需汇编编码。

如果您可以访问2008 WWDC会谈,Eric Postpischil就基本的矢量化技术进行了很好的讨论,他在其中编写了矢量代码来处理正是这个循环(在pSrc和英特尔的pDest是单精度阵列,但为了简单起见,他使用了C和矢量内在函数而不是ASM。

答案 3 :(得分:2)

所以这是针对一只手臂? (苹果手机?)。这些指针的大小(字节,半字,单词等?)是否存在对齐问题(在非字边界上复制单词)?如果这些是字节,那么生成的代码很可能很慢,优化器不能用它做太多。那你离开了哪里?你得到了你得到的。

以下是一个例子:

    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存储为字节

你必须回到原来的跛子mm和pp字节重新添加并存储gg和ii字节。

如果将上述所有内容保存在寄存器中并进行字存储而不是四字节存储,那么两个字读取应该明显快于四字节读取。这将节省相当多的时间。

你必须将很多寄存器保存到堆栈中,因此它会花费你那么你不想为a的小值(少于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

答案 4 :(得分: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

您可以在汇编程序中对其进行编码,但它可能不会更好。

答案 5 :(得分:0)

你说你正在为iPhone开发并且正在努力提高速度。看起来你正在尝试复制一块内存,你可能想要使用memcpy(dest, src, size)