Velocizzare operazioni su computer multiprocessor

di il
1 risposte

Velocizzare operazioni su computer multiprocessor

Buonasera, 

premetto che conosco java ma non ho mai usato i thread.
Avendo un computer multiprocessore volevo provare a velocizzare una routine inventata.
Di seguito il codice:

public class SimpleRunner extends Thread
{
private boolean stopThread = false;
private long[] p1={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
private long[] p2={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
private long[] p3={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
private long[] p4={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
private long[] p5={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
private long[] p6={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
private long[] p7={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
private long[] p8={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
 
 public void run()
 {
  while (! stopThread)
  {
	long prodotto=0;
  	for(int a=0;a<15;a++)
  		for(int b=0;b<15;b++)
  			for(int c=0;c<15;c++)
  				for(int d=0;d<15;d++)
  					for(int e=0;e<15;e++)
  						for(int f=0;f<15;f++)
  							for(int g=0;g<15;g++)
  								for(int h=0;h<15;h++)
  						{
  							if(p1[a]+p2[b]+p3[c]+p4[d]+p5[e]+p6[f]+p7[g]+p8[h]==120){
  								System.out.println(a+b+c+d+e+f);
  								stopRunning();
  							}
  						}
  	System.out.println("Finito!");
  	stopRunning();
  }
  }

 public void stopRunning()
 {
  stopThread = true;
 }
}

public class CalcoloNoThread {

	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		long inizio=System.currentTimeMillis();
		SimpleRunner t1=new SimpleRunner();
		SimpleRunner t2=new SimpleRunner();
		t1.start();
		t2.start();
		t1.join();
		t2.join();
		long fine=System.currentTimeMillis();
		System.out.println("Tempo impiegato:"+(fine-inizio)+" ms");
	}

}

Tuttavia eseguendo il codice sia t1 che t2 eseguono tutto ciò che è contenuto nel run(io pensavo che si tenesse memoria di dove si era giunti nei for innestati) aumentando i tempi al posto che diminuirli.
Dove sto sbagliando?

Stefano

1 Risposte

  • Re: Velocizzare operazioni su computer multiprocessor

    triack78 ha scritto:


    Tuttavia eseguendo il codice sia t1 che t2 eseguono tutto ciò che è contenuto nel run(io pensavo che si tenesse memoria di dove si era giunti nei for innestati) aumentando i tempi al posto che diminuirli.
    Dove sto sbagliando?
    Innanzitutto alcune premesse.

    1)
    Hai creato due istanze di SimpleRunner e questo per prima cosa vuol dire che ciascuno dei due oggetti ha i suoi propri campi p1, p2, ecc... Questo NON è un problema. Anche se ciascun oggetto SimpleRunner ha i suoi array p1, p2 ecc.. distinti da quelli dell'altro oggetto questi array non vengono modificati, quindi questa duplicazione non ha alcun impatto negativo. Potevi dichiarare i campi p1 p2 ecc.. come static in modo da essere davvero "globali" rispetto a tutte le istanze della classe. Ma ripeto, questo non è un problema.

    2)
    Hai usato due istanze diverse anche perché volevi gestire distintamente quel stopThread per ciascun thread, che potrebbe anche avere senso. Però per come l'hai usato attualmente NON ha senso e non ti serve.
    Se la somma di tutti i valori è 120 invochi stopRunning() ma questo cambia solo la variabile di istanza stopThread, NON fa terminare nulla.
    E oltretutto TUTTI i cicli continuano a ciclare perché il controllo while (! stopThread) è "a monte" di tutto.
    Quindi stopRunning() lì in quel punto NON ha senso e non serve. Se volevi che raggiunta la somma 120 TUTTI i cicli terminino, ci sono altre soluzioni:
    a) Fare un return (così però termina subito il run())
    b) Usare un break con "etichetta", una cosa un po' particolare ma molto utile.

    Ma ripeto che tutto questo non è il problema/punto principale. Quello che chiedevi è "dove sto sbagliando" rispetto alle prestazioni.

    La questione è che entrambi i thread fanno la stessa identica cosa e quindi non solo non stai abbreviando i tempi ma stai sprecando due flussi di esecuzione per fare gli stessi identici ragionamenti e con più o meno le stesse tempistiche.

    In scenari come questi l'obiettivo dovrebbe essere quello di "partizionare", suddividere il lavoro dei thread. Una soluzione banale, se hai 2 thread puoi fare in modo che il thread A usi solo gli indici PARI in p1 e il thread B usi solo gli indici DISPARI in p1. Questo fa sì che ciascun thread farà al massimo metà del lavoro complessivo e quindi uno dei due potrà arrivare più velocemente a trovare il risultato aspettato.
Devi accedere o registrarti per scrivere nel forum
1 risposte