【问题标题】:How to update all the elements in a double array in X86?如何在 X86 中更新双精度数组中的所有元素?
【发布时间】:2016-05-16 00:33:17
【问题描述】:

我是 X86 的新手,我一直坚持使用另一个双精度数组的值来更新双精度数组。以下代码是我的函数,我想使用内联汇编来替换循环内的一段代码。我在下面附上了错误消息。谁能帮我指出我的错误?我对错误消息感到困惑,不知道如何修改它。

static inline void update(double * x,double * y,double * z,double * vx,
        double * vy,double * vz,uint32_t size){
        for (uint32_t i=0;i<size;++i){
            x[i] = x[i] + vx[i];
            y[i] = y[i] + vy[i];
            z[i] = z[i] + vz[i];
        }
}
uint32_t counter = 0;
__asm__ __volatile__ (  
    "loop: \n\t" 
    "faddq (%4), (%1)\n\t"
    "faddq (%5), (%2)\n\t"
    "faddq (%6), (%3)\n\t"
    "addq $8, %1\n\t"
    "addq $8, %2\n\t"
    "addq $8, %3\n\t"
    "addq $8, %4\n\t"
    "addq $8, %5\n\t"
    "addq $8, %6\n\t"
    "incq %0\n\t"
    "cmp %0, %7\n\t"
    "jne loopb"
    : "+r"(counter)
    : "r" (x),"r" (y),"r"(z),"r"(vx),"r"(vy),"r"(vz),"r"(size) 
    : "memory", "cc");

错误信息:

update_locations_ass.c:150:15: error: invalid instruction mnemonic 'faddq'
        "loop: \n\t" 
                 ^
<inline asm>:2:2: note: instantiated into assembly here
        faddq (%rdi), (%rcx)
        ^~~~~
update_locations_ass.c:151:25: error: invalid instruction mnemonic 'faddq'
        "faddq (%4), (%1)\n\t"
                           ^
<inline asm>:3:2: note: instantiated into assembly here
        faddq (%r8), (%rdx)
        ^~~~~
update_locations_ass.c:152:28: error: invalid instruction mnemonic 'faddq'
        "faddq (%5), (%2)\n\t"
                           ^
<inline asm>:4:2: note: instantiated into assembly here
        faddq (%r9), (%rsi)
        ^~~~~
update_locations_ass.c:159:23: error: invalid operand for instruction
        "addq $8, %6\n\t"
                      ^
<inline asm>:11:7: note: instantiated into assembly here
        incq %eax

编译器版本: 配置: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM 版本 6.1.0 (clang-602.0.53)(基于 LLVM 3.6.0svn) 目标:x86_64-apple-darwin14.0.0 线程模型:posix

【问题讨论】:

  • 你用的是什么编译器?请不要发布错误消息的屏幕截图。将它们复制并粘贴到您的问题中。另外你为什么要在汇编中写这个?编译器可以生成更好的代码。
  • 它无法识别faddq 指令。可能你的编译器不支持 FPU..
  • 编译器是clang-602.0.53
  • @EugeneSh。它甚至不存在,不是编译器的错
  • 除非数据始终在 L1 中,否则此内核受带宽限制,不值得浪费时间编写汇编而不是 C。

标签: c arrays assembly x86 inline-assembly


【解决方案1】:

我在这里同样感到困惑。 faddq 是什么,你从哪里得到的?它应该是fadd 吗?无论如何,您不能将两个内存操作数与fadd 一起使用,因此代码看起来完全不正确。如果您对正确的执行方式感到好奇,请尝试使用 -S-O2 进行编译,以便查看优化的编译器输出。

如果您想获得该函数的更快版本,无论如何,最简单的方法就是在 C 中完成。假设数组不重叠,这里有一个更快的版本:

// Assuming x and vx do not overlap
void update1(double *restrict x, const double *restrict vx, unsigned count) {
    for (unsigned i = 0; i < count; i++) {
        x[i] += vx[i];
    }
}

void update(/* ... */) {
    update1(x, vx, count);
    update1(y, vy, count);
    update1(z, vz, count);
}

如果您使用-O3 进行编译,编译器将根据您的编译目标生成使用addpd 的代码。这将比您使用 x87 FPU 指令自己编写的任何内容都要好。

这些简单的函数——只是将数组添加到其他数组中——编译器很容易优化,所以除非你自学汇编语言,否则让编译器为你做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多