умножение массива и матрицы в мипах - PullRequest
0 голосов
/ 22 октября 2019

Я хочу умножить A X и суммировать с B. Таким образом, (A X) + B. Тем не менее, это не работает, и, кроме того, мне нужно найти максимальное число в результате AA составляет 5 * 3 матрицы и B является массивом, который равен 3, и C также является массивом из 5 чисел

Я спрашиваю, как исправитьэта ошибка и что не так в моем коде. Кроме того, я не могу сделать код, который находит максимальное число в результате матрицы A

ошибки таковы: Исключение произошло на ПК = 0x00400084 Неверный адрес в данных / стекечтение: 0x10040100 Исключительная ситуация на ПК = 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

1 Ответ

1 голос
/ 23 октября 2019

Я точно не понимаю ваш код. Вы утверждаете, что хотите сделать умножение матрицы на вектор, но в ваших комментариях у вас есть «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=0;i<N;i++){
    px=&x[0];
    r=*pb;
    for (j=O;j<M;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 @vectorX
        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:     move $t1,$0         # i=0
        move $s4,$s3        # $s4 == px
        l.d $f0,0($s2)      # f0=r=*pb

L2:     move $t2,$0         # j=0
        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,$s6,L2     # j!=N?->L2

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

РЕДАКТИРОВАТЬ: исправлены ошибки (спасибо @Peter)

...