Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Java программирование > Общие вопросы по Java, Java SE, Kotlin
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.05.2019, 21:31   #1
SadiQ228
Пользователь
 
Регистрация: 30.10.2017
Сообщений: 66
По умолчанию многопоточное умножение матриц

Это мой класс матрицы:
Код:
import java.util.Random;
 
public class UsualMatrix{
 
    protected volatile int matrix[][];
    
    public UsualMatrix(int row, int column){
        matrix = new int[row][column];
        }
    
    public UsualMatrix randThisMatrix() {   
    Random randomizer = new Random(System.currentTimeMillis());
        for(int i=0; i < this.matrix.length; i++) {
            for(int j=0; j < this.matrix[0].length; j++) {
                    this.matrix[i][j] = 1 + randomizer.nextInt(5-1);
                    }
            }
        return null;
        }
    
    public UsualMatrix productMatrix(UsualMatrix obj) {
                UsualMatrix tmp = new UsualMatrix(this.matrix.length, obj.matrix[0].length);
                for (int i = 0; i < this.matrix.length; i++) {
                    for (int j = 0; j < obj.matrix[0].length; j++) {
                        for (int k = 0; k < this.matrix[0].length; k++) {
                            tmp.matrix[i][j] += matrix[i][k] * obj.matrix[k][j]; 
                        }
                    }
                }
                return tmp;
    }
    
    @Override
    public String toString() {
        StringBuilder build = new StringBuilder();
        for(int i = 0; i < matrix.length; ++i) {
            for(int j = 0; j < matrix[0].length; ++j) {
                build.append("[").append(this.matrix[i][j]).append("]"); 
            }
            build.append("\n");
        }
        return build.toString();
    }
}


Это мой класс Runnable:
Код:
public class ParallelMatrixProduct implements Runnable{
    private int index;
    private UsualMatrix a;
    private UsualMatrix b;
    
    ParallelMatrixProduct(UsualMatrix a, UsualMatrix b, int index){
        this.a = a;
        this.b = b;
        this.index = index;
    }
    
    @Override
    public void run(){
        productMatrix();
        }
    
    public void productMatrix() {
        for (int j = 0; j < b.matrix[0].length; j++) {
            for (int k = 0; k < a.matrix[0].length; k++) {
                Main.multiResult.matrix[index][j] += a.matrix[index][k] * b.matrix[k][j];
                }
            }
        }
 
}
это MAIN:
Код:
import java.math.BigDecimal;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class Main {
    static UsualMatrix aMtrx;
    static UsualMatrix bMtrx;
    static UsualMatrix oneResult;
    static UsualMatrix multiResult;
    
    public static void main(String[] args) throws InterruptedException {
        aMtrx = new UsualMatrix(5,6);
        aMtrx.randThisMatrix();
        //System.out.print(aMtrx);
        bMtrx = new UsualMatrix(6,5);
        bMtrx.randThisMatrix();
        //System.out.print(bMtrx);
        oneResult = new UsualMatrix(aMtrx.matrix.length, bMtrx.matrix[0].length);
        multiResult = new UsualMatrix(aMtrx.matrix.length, bMtrx.matrix[0].length);
        
        
        BigDecimal timeStart = new BigDecimal( System.nanoTime());
        oneResult = aMtrx.productMatrix(bMtrx);
        BigDecimal nanos = new BigDecimal( System.nanoTime()).subtract(timeStart);
        BigDecimal millis = nanos.divide(new BigDecimal(1000000));
        BigDecimal seconds = millis.divide(new BigDecimal(1000));
        System.out.print(oneResult);
        System.out.println(nanos+" ns"); System.out.println(millis+" ms"); System.out.println(seconds+" sec\n");
        
        
        
        
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        BigDecimal timeStart1 = new BigDecimal( System.nanoTime());
        for(int i = 0; i < aMtrx.matrix.length; i++) {
            executorService.submit(new ParallelMatrixProduct(aMtrx, bMtrx,i));
        }
        executorService.shutdown();
        BigDecimal nanos1 = new BigDecimal( System.nanoTime()).subtract(timeStart1);
        BigDecimal millis1 = nanos1.divide(new BigDecimal(1000000));
        BigDecimal seconds1 = millis1.divide(new BigDecimal(1000));
        System.out.print(multiResult);
        System.out.println(nanos1+" ns"); System.out.println(millis1+" ms"); System.out.println(seconds1+" sec");
    }
 
}
заппускаю пока на не больших матрицах чтобы можно было посчитать устно и проверить результат, как видно даже маленькие матрицы не выигрывают по времени в многопоточном режиме, более того получаются нулевые элементы в результате:
Цитата:
[35][28][47][35][45]
[23][21][36][26][30]
[40][30][55][42][52]
[40][35][54][38][47]
[47][36][48][45][47]
46316 ns
0.046316 ms
0.000046316 sec

[35][28][47][35][45]
[23][21][36][26][30]
[0][0][0][0][0]
[0][0][0][0][0]
[47][36][48][45][47]
4553116 ns
4.553116 ms
0.004553116 sec

из за чего это происходит что делаю не так? как нужно рассуждать при разбиении задачи на подзадачи для потоков?
SadiQ228 вне форума Ответить с цитированием
Старый 14.05.2019, 11:23   #2
challengerr
Участник клуба
 
Аватар для challengerr
 
Регистрация: 30.07.2008
Сообщений: 1,639
По умолчанию

запустил ваш код - ошибку не вижу, а она есть.... действительно выдает нули.
"SPACE.THE FINAL FRONTIER.This's a voyage of starship Enterprise. It's 5-year mission to explore strange new worlds,to seek out new life and civilizations,to boldly go where no man has gone before"
challengerr вне форума Ответить с цитированием
Старый 23.05.2019, 01:19   #3
SadiQ228
Пользователь
 
Регистрация: 30.10.2017
Сообщений: 66
По умолчанию

да все уже: происходит это потому что некоторые потоки еще не заончили работу в этот момент, так если потыкать, то нулей не будет)
связанно это с неизвестными мне штуками в нутри реализации пула...
вот прилогаю делюкс эдишен, где работает как заказывали:
Код:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ParallelMatrixProduct {
	private int number_of_threads;
	private UsualMatrix a;
	private UsualMatrix b;
	private UsualMatrix rez;
	
	private class myThread implements Runnable{
		private int stringIndex;

        public myThread(int index) {
            this.stringIndex = index;
        }
        @Override
    	public void run(){
    		for (int j = 0; j < b.matrix[0].length; j++) {
    			for (int k = 0; k < a.matrix[0].length; k++) {
    				rez.matrix[this.stringIndex][j] += a.matrix[this.stringIndex][k] * b.matrix[k][j];
    				}
    			}
            }
		}
	
	ParallelMatrixProduct(UsualMatrix a, UsualMatrix b, int number_of_threads){
		this.a = a;
		this.b = b;
		this.number_of_threads = number_of_threads;
		this.rez = new UsualMatrix(a.matrix.length, b.matrix[0].length);
	}
	
	public UsualMatrix parallelProduct() throws InterruptedException {
		ExecutorService executorService = Executors.newFixedThreadPool(this.number_of_threads);
		for(int i = 0; i < a.matrix.length; i++)
			executorService.execute(new myThread(i));
		executorService.shutdown();
		executorService.awaitTermination(1, TimeUnit.MINUTES);
		return this.rez;
	}
}
Код:
public class Main {

	public static void main(String[] args) throws InterruptedException {
		UsualMatrix aMtrx = new UsualMatrix(1000,1000);
		aMtrx.randThisMatrix();
		UsualMatrix bMtrx = new UsualMatrix(1000,1000);
		bMtrx.randThisMatrix();
		UsualMatrix oneResult;
		UsualMatrix multiResult;
		
		long startTime = System.currentTimeMillis();
		oneResult = aMtrx.productMatrix(bMtrx);
		long estimatedTime = System.currentTimeMillis() - startTime;
		//System.out.print(oneResult);
		System.out.println("Умножается за время: " + estimatedTime + "ms");
		
		ParallelMatrixProduct test = new ParallelMatrixProduct(aMtrx, bMtrx, Runtime.getRuntime().availableProcessors());
		long startTime1 = System.currentTimeMillis();
		multiResult = test.parallelProduct();
		long estimatedTime1 = System.currentTimeMillis() - startTime1;
		//System.out.print(multiResult);
		System.out.println("Умножается за время: " + estimatedTime1 + "ms");
	}

}
SadiQ228 вне форума Ответить с цитированием
Старый 23.05.2019, 01:21   #4
SadiQ228
Пользователь
 
Регистрация: 30.10.2017
Сообщений: 66
По умолчанию

на моих 4 ядрах в четыре считай потока выигрываю в скорости обычное умножение 10-11 сек, многопоточное 3-4 сек
SadiQ228 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C++ Многопоточное умножение матриц Harbinger Помощь студентам 0 03.11.2015 15:56
Умножение матриц MJBuster C# (си шарп) 2 01.04.2013 13:29
Умножение матриц BDA Общие вопросы C/C++ 2 20.11.2011 01:06
умножение матриц Rusya_00 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 06.01.2011 23:51
умножение матриц Mila Volkova Помощь студентам 3 25.12.2010 14:17