我正在为嵌入式计算机编写一个程序,并且具有很少的内存和处理能力。
y 和 a 是存储在浮点寄存器中的双精度数, x 是数组的双精度数 。在MIPS中编写此表达式的最有效方法是什么?
y = y + a * x[i];
答案 0 :(得分:0)
我不熟悉MIPS汇编程序,因此我不会理会实际的MIPS指令,我将使用简单的英语到z80 / x86 TASM,希望你能得到这个想法。
我假设你想要添加一个完整的数组,而不仅仅是这一行,因为这会改变任务的所有内容。
如果你真的想要优化这条单线,那么它的空间很小。只需加载x [i],将其乘以a,然后将结果添加到y。
如果你在谈论一些固定大小的数组(比如矩阵中的大小为4),可能会有一些直接展开的方式比我下面的东西更快。
如果我们谈论某些数组,那就不同了(但你应该这样发布),你可以保存很多(n-1)通过首先对x数组求和来进行乘法运算:
load r1, x_array_pointer
load r2, x_array_end_pointer
load fpr0, zero_value
:loop_sum_x_array
add fpr0,[r1]
add r1,size_of_double
cmp r1,r2
jump_less loop_sum_x_array ; till whole array is summed
mul fpr0, *a* ; now multiply sum{x} by "a"
add fpr0, *y* ; and add initial "y" value
; fpr0 contains result
"算法":y + a * x0 + a * x1 + a * x2 + ... = y + a *(x0 + x1 + x2 + .. 。)(如果你在SO发布之前没有自己想出这个,你要么没有尝试,要么你已经8岁了,或者你应该认真做一些思考和基本数学练习,因为这很明显。嘿,实际上,在这个难度级别,它是纯粹的乐趣,为什么你让其他人生活在你的有趣?你是非常慷慨的先生。 :))
内存:这不会使用任何额外的内存,只有输入 y , a 和 x ,你需要一些临时的寄存器(r1,r2,fpr0)(所以只要你没有进行8位CPU运算,就应该有足够的备用电源)。
处理能力:算法的复杂性是O(n)(因为你必须从x数组中添加每个值,你不能超过它)。内部循环使用非常基本的指令:一个浮点加法,从内存加载双值,地址递增,比较和条件跳转。然后它需要字面上一个浮点乘法和另外一个fp加法。 x数组是按顺序访问的,因此内存缓存未命中应该是最小的。
如果您的CPU有像MMX这样的专门指令,那么使用这些指令可以更快地写入大型数组的总和。但是对于大型阵列的现代CPU + RAM,您将主要受内存缓存速度的限制,因为内部循环与GHz CPU不同(当然,从内存加载值除外)。
编辑:正如Michael所说,使用C编译器是正确的方法,我的答案只是为了编写一些伪汇编程序。我不确定你的平台是什么,但如果它有价值,那么必须有PC的交叉编译器以及将二进制结果送到目标的方式。