数组中的矩阵和矩阵相乘

问题描述 投票:0回答:2

我想将A X乘以B。因此,(A X)+ B。但是,它不起作用,另外我需要在A的结果中找到最大数A是5 * 3矩阵,B是3的数组,C也是5个数字的数组

我问如何解决该错误以及我的代码中有什么错误另外,我无法使代码在矩阵A

的结果中找到最大数

错误是这样的:PC = 0x00400084发生异常数据/堆栈中的错误地址读取:0x10040100PC = 0x00400084发生异常数据/堆栈中的错误地址读取:0x10040114

la $s4, matrixA     #s4 set to base address of matrixA
la $s3, vectorX     #s3 set to base address of vectorX
la $s7, vectorB     #s7 set to base address of vectorB
la $s5, shapeA       #s5 set to base address of sizeA
nop
lw $s6, 4($s5)      #s6 set to second val in sizeA (col#)
nop
lw $s5, 0($s5)      #s5 set to first val in sizeA (row#)

lw $t1, 0($s5) # $t1 = 32 (row size/loop end)
li $s0, 0  # i = 0; initialize 1st for loop
L1:  li $s1,0  #j=0;restart2ndforloop
L2:  li $s2,0  #k=0;restart3rdforloop

mul $t2, $s0, $s5 #$t2 = A[row](size of row of B)
addiu $t2, $t2, 0 # $t2 = i * size(row) + 0
sll  $t2, $t2, 2   # $t2 = byte offset of [i][0]
addu $t2, $s7, $t2 # $t2 = byte address of B[i][0]
l.d $f4, 0($t2) # $f4 = 4 bytes of B[i][0]

L3: mul $t0,$s2,$s5   #$t0 = i * A[col](size of row of X)
addiu $t0, $t0, 0 # $t0 = k * size(row) + 0
sll  $t0, $t0, 2   # $t0 = byte offset of X[k][0]
addu $t0, $s3, $t0 # $t0 = byte address of X[k][0]
l.d $f16, 0($t0)   # $f16 = 4 bytes of X[k][0]

mul $t0,$s0,$s5 #$t0 = i * A[row](size of row of A)
addu $t0, $t0, $s2 # $t0 = i * size(row) + k
sll $t0, $t0, 2 # $t0 = byte offset of A[i][k]
addu $t0, $s4, $t0   # $t0 = byte address of A[i][k]
l.d $f18, 0($t0)   # $f18 = 4 bytes of A[i][k]

mul.d $f16, $f18, $f16 # $f16 = y[i][k] * z[k][j]
add.d $f4, $f4, $f16 # $f4=x[i][j] + y[i][k]*z[k][j]

addiu $s2, $s2, 1 # k = k + 1
bne $s2,$t1,L3
s.d $f4, 0($t2)

addiu $s2, $s2, 1 # j = j + 1
bne $s2,$t1,L2
addiu $s0, $s0, 1 # i = i + 1
bne $s0,$t1,L1 #if(i!=32)gotoL1
assembly mips matrix-multiplication
2个回答
1
投票

我绝对不理解您的代码。您声明要进行矩阵矢量乘法,但是在注释中有“ x [i] [j] + y [i] [k] * z [k] [j]”。当我看到地址计算时,我觉得您正在处理浮点数,但是在代码中,它似乎与双精度有关。...

矩阵矢量乘法不需要复杂的地址计算,可以通过仅增加指针来完成。

您有兴趣在代码中分离循环计数和地址计算,并反转循环。

C代码b [] + = a [] [] * x []

  for(i=0;i<N;i++){
    double r=b[i];
    for(j=0;j<M;j++){
      r+=a[i][j]*x[j];
    }
    b[i]=r;
  }

可以用指针并通过反转循环来重写

  pb=&b[0] ;
  pa=&a[0][0];
  for (i=N;i>0;i--){
    px=&x[0];
    r=*pb;
    for (j=M;j>0;j--){
      r = r + *px * *pa;
      px++;
      pa++;
    }
    *pb=r ;
    pb++ ;
  }

和mips版本,即后者C代码的直接翻译

        la $s1, matrixA     #s1 set to base address of matrixA pa
        la $s2, vectorB     #s2 set to base address of vectorB pb
        la $s3, vectorX     #s3 set to base address of vectorX px
        # s4 temps for the vector x
        la $s5, shapeA      #s5 set to base address of sizeA
        lw $s6, 4($s5)      #s6 set to second val in sizeA (col#)
        lw $s5, 0($s5)      #s5 set to first val in sizeA (row#)

L1:     li $t1,$s5          # i=M
        move $s4,$s3        # $s4 == px
        l.d $f0,0($s2)      # f0=r=*pb

L2:     li $t2,$s6          # j=N
        l.d $f2,0($s1)      # $f2 *pa=a[i]][j]
        l.d $f4,0($s4)      # $f4 *px=x[j]
        mul.d $f2,$f2,$f4   # a[i][j]*x[j]
        add.d $f0,$f0,$f2   # +b[i]
        addi $t2,$t2,-1     # j--
        addi $s1,$s1,8      # pa++
        addi $s4,$s4,8      # px++
        bne  $t2,L2         # j>0?->L2

        s.d  $f0,0($s2)     # *pb=r
        addi $s2,$s2,8      # pb++
        addi $t1,$t1,-1     # i--
        bne  $t1,L1         # j>0?->L1

0
投票

main:

    la $s1, matrixA     #s1 set to base address of matrixA pa
    la $s2, vectorB     #s2 set to base address of vectorB pb
    la $s3, vectorX     #s3 set to base address of vectorX px
    # s4 temps for the vector x
    la $s5, shapeA      #s5 set to base address of sizeA
    lw $s6, 4($s5)      #s6 set to second val in sizeA (col#)
    lw $s5, 0($s5)      #s5 set to first val in sizeA (row#)

    L1:     lw $t1,0($s5)          # i=M
    move $s4,$s3        # $s4 == px
    l.d $f0,0($s2)      # f0=r=*pb

    L2:     lw $t2,4($s5)        # j=N
    l.d $f2,0($s1)      # $f2 *pa=a[i]][j]
    l.d $f4,0($s4)      # $f4 *px=x[j]
    mul.d $f2,$f2,$f4   # a[i][j]*x[j]
    add.d $f0,$f0,$f2   # +b[i]
    addi $t2,$t2,-1     # j--
    addi $s1,$s1,8      # pa++
    addi $s4,$s4,8      # px++
    slt  $t5,$zero,$t2
    bne  $t5,$zero,L2        # j>0?->L2

    s.d  $f0,0($s2)     # *pb=r
    addi $s2,$s2,8      # pb++
    addi $t1,$t1,-1     # i--
    slt  $t5,$zero,$t1
    bne  $t5,$zero,L1        # i>0?->L1

    # print the values of y,
    # where y = max(0, matrixA * vectorX + vectorB)

   li $v0, 4 # system call code for printing string = 4
   la $a0, str1
   syscall # call operating system to perform operation

   # printing shape
   li $v0, 1
   la $s0, shapeA
   lw $a0, 0($s0)
   syscall

   li $v0, 4 # system call code for printing string = 4
   la $a0, space
   syscall # call operating system to perform operation

   li $v0, 1
   lw $a0, 4($s0)
   syscall

   li $v0, 4 # system call code for printing string = 4
   la $a0, str2
   syscall # call operating system to perform operation

   # printing the first two elements
   li $v0, 2
   la $s1, matrixA
   lwc1 $f12, 0($s1)
   syscall

   li $v0, 4 # system call code for printing string = 4
   la $a0, space
   syscall # call operating system to perform operation

   li $v0, 2
   lwc1 $f12, 4($s1)
   syscall

我这样更改了它,但它正在产生异常错误

© www.soinside.com 2019 - 2024. All rights reserved.