О наблюдении из 6 комбинаций модели ijk для умножения матриц - PullRequest
1 голос
/ 10 января 2020

Мы пробовали все 6 комбинаций модели ijk (т.е. IJK, JIK, KIJ, IKJ, JKI, KJI) для умножения матриц, чтобы наблюдать разницу во времени, взятую каждой комбинацией. Мы сделали скрипт и запустили его на ноутбуке с Intel i7 9750H и Windows 10 для наших наблюдений.

Мы измеряли время и размер массива. Проблема в том, что график, который мы получаем из наших наблюдений, не согласуется с теорией различий в производительности всех комбинаций, т.е. внутренний l oop, который должен проходить последовательно, будет иметь низкое количество кеш-пропусков и лучшую производительность и внутренний l oop Обход по столбцу будет иметь максимальные потери в кеше и худшую производительность.

Это график из наших наблюдений: Наш график

Это наша ссылка graph: Наша справка

Хотя график имеет циклы на внутреннюю итерацию l oop в зависимости от размера массива, не должно ли время и размер массива быть чем-то похожим на него? Является ли наш метод или код для наблюдения неправильным? Мы не можем найти ошибку и не можем сделать вывод. Было бы замечательно, если бы кто-нибудь мог указать нам, где мы идем не так.

Код, который мы использовали для наблюдения:

import time
import numpy as np
import random
import csv

#size = int(input("Enter the size of arrays: "))
# []
sizeArr = np.array([100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700], dtype=int)

for size in sizeArr:
    with open('observation.csv', 'a+') as file:
        writer = csv.writer(file)

        print(f"Size -> {size}\n")
        writer.writerow([f"Size -> {size}"])
        # Initialize for all the sizes
        A = np.zeros((size, size), dtype=int)
        B = np.zeros((size, size), dtype=int)
        C = np.zeros((size, size), dtype=int)

        # Filling arrays with random numbers
        for a in range(size):
            for b in range(size):
                A[a][b] = random.randrange(1, 101, 1)
                B[a][b] = random.randrange(1, 101, 1)

        # ijk
        before = time.time()
        for i in range(size):
            for j in range(size):
                C[i][j] = 0
                for k in range(size):
                    C[i][j] += A[i][k] * B[k][j]
        after = time.time()
        timeTaken = int(after - before)
        print(f"Time taken by ijk -> {timeTaken}")
        writer.writerow([f"Time taken by ijk -> {timeTaken}"])

        # Reset C elements to 0
        C = np.zeros((size, size), dtype=int)

        # Filling arrays with random numbers
        for a in range(size):
            for b in range(size):
                A[a][b] = random.randrange(1, 101, 1)
                B[a][b] = random.randrange(1, 101, 1)

        # jik
        before = time.time()
        for j in range(size):
            for i in range(size):
                C[i][j] = 0
                for k in range(size):
                    C[i][j] += A[i][k] * B[k][j]
        after = time.time()
        timeTaken = int(after - before)
        print(f"Time taken by jik -> {timeTaken}")
        writer.writerow([f"Time taken by jik -> {timeTaken}"])

        # Reset C elements to 0
        C = np.zeros((size, size), dtype=int)

        # Filling arrays with random numbers
        for a in range(size):
            for b in range(size):
                A[a][b] = random.randrange(1, 101, 1)
                B[a][b] = random.randrange(1, 101, 1)

        # kij
        before = time.time()
        for k in range(size):
            for i in range(size):
                temp = A[i][k]
                for j in range(size):
                    C[i][j] += temp * B[k][j]
        after = time.time()
        timeTaken = int(after - before)
        print(f"Time taken by kij -> {timeTaken}")
        writer.writerow([f"Time taken by kij -> {timeTaken}"])

        # Reset C elements to 0
        C = np.zeros((size, size), dtype=int)

        # Filling arrays with random numbers
        for a in range(size):
            for b in range(size):
                A[a][b] = random.randrange(1, 101, 1)
                B[a][b] = random.randrange(1, 101, 1)

        # ikj
        before = time.time()
        for i in range(size):
            for k in range(size):
                temp = A[i][k]
                for j in range(size):
                    C[i][j] += temp * B[k][j]
        after = time.time()
        timeTaken = int(after - before)
        print(f"Time taken by ikj -> {timeTaken}")
        writer.writerow([f"Time taken by ikj -> {timeTaken}"])

        # Reset C elements to 0
        C = np.zeros((size, size), dtype=int)

        # Filling arrays with random numbers
        for a in range(size):
            for b in range(size):
                A[a][b] = random.randrange(1, 101, 1)
                B[a][b] = random.randrange(1, 101, 1)

        # jki
        before = time.time()
        for j in range(size):
            for k in range(size):
                temp = B[k][j]
                for i in range(size):
                    C[i][j] += A[i][k] * temp
        after = time.time()
        timeTaken = int(after - before)
        print(f"Time taken by jki -> {timeTaken}")
        writer.writerow([f"Time taken by jki -> {timeTaken}"])

        # Reset C elements to 0
        C = np.zeros((size, size), dtype=int)

        # Filling arrays with random numbers
        for a in range(size):
            for b in range(size):
                A[a][b] = random.randrange(1, 101, 1)
                B[a][b] = random.randrange(1, 101, 1)

        # kji
        before = time.time()
        for k in range(size):
            for j in range(size):
                temp = B[k][j]
                for i in range(size):
                    C[i][j] += A[i][k] * temp
        after = time.time()
        timeTaken = int(after - before)
        print(f"Time taken by kji -> {timeTaken}")
        writer.writerow([f"Time taken by kji -> {timeTaken}"])
        print("\n")

...