У меня есть вопрос о параллельном программном обеспечении java.Java Concurrent - нет speedUp получил алгоритм LU - Ложное разделение?
Основным алгоритмом моего приложения является фактор матрицы A
в LU
матриц: A = LU. Метод разложения, вставленный здесь, приводит к уменьшению Гаусса-Иордана. Программное обеспечение предназначено для работы на квадратной матрице с позицией A[0][0] != 0
.
К сожалению, для правильной работы алгоритма мне нужно подождать, чтобы каждая строка знаменует значения.
Я попытался сделать этот алгоритм параллельно с использованием барьера (для ждать актуализацию каждой строки и приращения «rigaCorrente» значения), но я не получить реальный SpeedUp, даже если в параллельной версии моих процессоры (2,4 ГГц Core 2 Duo P8600) работают на 80% от общего количества (вместо 40-50% серийного).
Мой страх в том, что я столкнулся с ложным обменом ситуация. Является ли проблема связана с ложным обменом или с другими вопросами? Я знаю, что JVM выполняет хорошие оптимизации, но по-прежнему использует половину мощности процессора. Я не думаю, что невозможно улучшить алгоритм!
Мой серийный код:
public void decompose(){
int n = A.length;
for(int k=0; k<n-1;k++) {
for(int i=k+1; i<n; i++) {
A[i][k] = A[i][k]/A[k][k];
for(int j=k+1; j<n; j++) {
A[i][j] = A[i][j] - A[i][k] * A[k][j];
}
}
}
decomposed = true;
}
Мои параллельно код:
public class Manager {
private double [][] A;
private Semaphore main = new Semaphore(0);
private CyclicBarrier barriera;
private AtomicInteger index;
private int rigaCorrente = 0;
private boolean stop = false;
public Manager(final double A[][], final int numThr){
this.A = A;
this.index = new AtomicInteger(1);
barriera = new CyclicBarrier(numThr, new Runnable(){
@Override
public void run() {
rigaCorrente++;
index = new AtomicInteger(rigaCorrente+1);
if(rigaCorrente == A.length - 1){
setStop(true);
main.release();
}
}
});
}
Класс резьбы:
public class Deco implements Runnable {
private Manager manager;
public Deco(Manager manager){
this.manager = manager;
}
@Override
public void run() {
double [][] A = manager.getA();
while(manager.getStop() == false){
int i;
while((i = (manager.getIndex().getAndIncrement())) < (A.length)){
double pivot = A[i][manager.getRigaCorrente()]/A[manager.getRigaCorrente()] [manager.getRigaCorrente()];
for(int k = manager.getRigaCorrente(); k<A.length; k++)
A[i][k] = A[i][k] - (pivot*A[manager.getRigaCorrente()][k]);
A[i][manager.getRigaCorrente()] = pivot;
}
manager.acquireBarriera();
}// Stop
}
}
Главное для параллельного кода:
package luConcurrent.test;
import java.util.Arrays;
import java.util.Scanner;
import lu.DecompositionLU;
import lu.IO;
public class Starter {
private static IO io;
private static DecompositionLU dec;
public static void main(String[] args) throws Exception {
io = new IO("//Users//black//Desktop//serie//2500.txt");
int numThr = 2;
double [][] A = io.readMatrixFromInputFile();
double [] b = io.readArrayFromInputFile();
double [] x;
dec = new DecompositionLU(A);
System.out.println("A.length: "+A.length);
Manager manager = new Manager(A,numThr);
Thread[] pool = new Thread[numThr];
for(int i=0; i<pool.length; i++){
pool[i] = new Thread(new Deco(manager));
}
long inizio = System.nanoTime();
for(int i = 0; i<pool.length; i++){
pool[i].start();
}
manager.getMain().acquire();
dec.ProgresiveSustitution(b);
x = dec.RegresiveSustitution(b);
long fine = System.nanoTime()-inizio;
System.out.println("Solution is: "+Arrays.toString(x));
Scanner sc = new Scanner(System.in);
sc.nextLine();
System.out.println("Tempo: "+fine);
sc.close();
}
}
Результаты:
1000x1000 Serial: 1154679000 nanoSec
1000x1000 Parallel 2 Threads: 1135663000 nanoSec
1750x1750 Serial: 7502559000 nanoSec
1750x1750 Parallel 2 Threads: 6667129000 nanoSec
4000x4000 Serial: 89851311000 nanoSec
4000x4000 Parallel 2 Threads: 84348616000 nanoSec
можете ли вы разместить больше кода и, возможно, пропустить несколько пустых строк? –
у вас есть большое количество промахов в L2? Если происходит ложное совместное использование, вы можете передать каждому потоку свою собственную копию массива, чтобы полностью избежать перезаписи кэша L2 каждого ядра. – anguyen
Я не знаю, есть ли у меня большое количество промахов, как это проверить? – BlacK