示例#1
0
        public UnsafeMatrix <T> Multiply <T>(UnsafeMatrix <T> a, UnsafeMatrix <T> b, int blockSize)
        {
            if (!a.CanMultiplyWith(b))
            {
                throw new ArgumentException();
            }

            int ar = a.Rows;
            int ac = a.Columns;
            int br = b.Rows;
            int bc = b.Columns;

            if (ar % blockSize != 0 || ac % blockSize != 0 ||
                br % blockSize != 0 || bc % blockSize != 0)
            {
                throw new IndexOutOfRangeException();
            }

            UnsafeMatrix <T> result = new UnsafeMatrix <T>(new T[ar, bc]);

            int processCount            = (ar * bc) / (blockSize * blockSize);
            int blocksPerProcess        = ac / blockSize;
            int multiplicationsPerBlock = bc / blockSize;

            Thread[] threads = new Thread[processCount];

            for (int i = 0; i < processCount; i++)
            {
                UnsafeMatrix <T>[] blocksA = new UnsafeMatrix <T> [blocksPerProcess];
                UnsafeMatrix <T>[] blocksB = new UnsafeMatrix <T> [blocksPerProcess];

                int row = (i / multiplicationsPerBlock) * blockSize;
                int col = (i % multiplicationsPerBlock) * blockSize;

                for (int j = 0; j < blocksPerProcess; j++)
                {
                    blocksA[j] = a.GetBlock(row, j * blockSize, blockSize, blockSize);
                    blocksB[j] = b.GetBlock(j * blockSize, col, blockSize, blockSize);
                }

                threads[i] = new Thread(() => Multiply(result, blocksA, blocksB, row, col, blockSize));
                threads[i].Start();
            }

            foreach (Thread t in threads)
            {
                t.Join();
            }

            return(result);
        }
示例#2
0
        private static void Multiply <T>(
            UnsafeMatrix <T> result,
            UnsafeMatrix <T>[] blocksA,
            UnsafeMatrix <T>[] blocksB,
            int row,
            int col,
            int size)
        {
            Debug.Assert(blocksA.Length == blocksB.Length);

            UnsafeMatrix <T> sumOfProducts = null;

            for (int k = 0; k < blocksA.Length; k++)
            {
                UnsafeMatrix <T> toAdd = blocksA[k].Mul(blocksB[k]);
                sumOfProducts = sumOfProducts == null ? toAdd : sumOfProducts + toAdd;
            }

            result.SetBlock(row, col, sumOfProducts);
        }