iT邦幫忙

1

[JAVA] 計算執行緒花費時間

請問各位神人大大,小弟想用JAVA計算執行緒的執行時間

具體內容主要是想用多執行緒處理矩陣相乘的問題,並計算從開始第一個執行緒到執行完最後一個執行緒之間經過的時間

小弟讓每個執行緒計算相乘後某個元素的值,比如一個n*m的矩陣A乘上m*p的矩陣B會等於一個n*p的矩陣C,總共會有n*p個執行緒,其中第[i][j]個執行緒就會計算第C的第[i][j]個元素的值

程式碼如下:

import java.util.*;
import java.io.*;

//矩陣抽象類別
abstract class MatrixMultiple
{
	protected static int n,m,p;
	public MatrixMultiple(int n1,int n2,int n3)
	{
		n=n1;
		m=n2;
		p=n3;
	}
}

//Concurrency類別
class Concurrency extends MatrixMultiple implements Runnable
{
	protected int row,col;
	protected int[] a,b;
	protected static int[][] c;
	public Concurrency(int n1,int n2,int n3,int[][] a1,int[][] a2,int n4,int n5)
	{
		super(n1,n2,n3);
		a=new int[n2];
		b=new int[n2];
		c=new int[n1][n3];
		row=n4;
		col=n5;
		for(int i=0;i<n2;i++)
		{
			int s;
			a[i]=a1[n4][i];
			b[i]=a2[i][n5];
		}
	}
	public void run()
	{
		for(int i=0;i<m;i++)
		{
			c[row][col]+=a[i]*b[i];
			System.out.printf("%d %d run\n",row,col);  //顯示此執行緒開始執行
		}
	}
}

public class timer
{
	public static void main(String args[]) throws IOException
	{
		FileReader fr = new FileReader("input.txt"); //連結檔案
		BufferedReader br = new BufferedReader(fr);  //啟用Buffer
		Scanner in =new Scanner(br);				 //連結輸入流
		
		//讀入n,m
		int n,m;
		n=in.nextInt();
		m=in.nextInt();
		
		//讀入矩陣
		int a[][]=new int[n][m];
		int b[][]=new int[m][n];
		
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				a[i][j]=in.nextInt();
			
		for(int i=0;i<m;i++)
			for(int j=0;j<n;j++)
				b[i][j]=in.nextInt();
		
		//建立物件
		Concurrency concurrency[][]= new Concurrency[n][n];
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				concurrency[i][j]=new Concurrency(n,m,n,a,b,i,j);
		
		//建立執行緒
		Thread t[][]=new Thread[n][n];
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				 t[i][j]=new Thread(concurrency[i][j]);
		
		//執行&算時間
		long concurrencyStart,concurrencyFin;
		
		concurrencyStart=System.currentTimeMillis();
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				t[i][j].start();
		concurrencyFin=System.currentTimeMillis();
		
		System.out.println(concurrencyStart); //顯示開始時間
		System.out.println(concurrencyFin);  //顯示結束時間
		
		fr.close(); //關閉檔案串流
	}
}

而執行結果如下:

0 0 run
1 1 run
1 1 run
1464149482319  <-迴圈開始跑
1464149482319  <-迴圈跑完
1 0 run
0 1 run
1 0 run
0 0 run
0 1 run

小弟想問的是:
有沒有辦法能取得"最後一個執行緒跑完的時間點"?

fillano iT邦超人 1 級 ‧ 2016-05-25 15:17:17 檢舉
每一個執行緒執行完都丟一個時間點,比較一下就知道了吧?要知道是那個執行緒,把傳給他的i, j也丟出來就可以辨認了。
感謝幫忙,我要做的是比較直接運算和使用執行緒的速度差異,所以不希望執行緒除了計算上不要有而外的動作,如果每個執行緒都有這個動作,當執行緒一多,應該會有誤差,比較希望能夠只讓最後一個執行完的有這個動作,不知道有沒有相關的方法能用,不過還是非常感謝你的回答~
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
weiclin
iT邦高手 4 級 ‧ 2016-05-25 13:17:45

你知道 thread 有個 join ?

偷懶一點, 全部 join 完再計算結束時間就好了

看更多先前的回應...收起先前的回應...

謝謝回答~
不過join好像一次只能一個執行緒,這樣好像就變成按照順序執行了...
有沒有可能一次join一堆執行緒??

weiclin iT邦高手 4 級 ‧ 2016-05-25 21:36:57 檢舉

join 不是按順序執行的意思, 比較像是等待他執行結束

所以你一次啟動許多個 thread, 然後按順序 join 等他跑完, 也不會有太大的誤差

假設 join 一個 thread 要 0.01 秒好了(實際上比這快很多), 而你開了 10 個 thread

然後很衰的第一個 join 的就是最後跑完的, 就算這樣, 你也只多計算了 0.09 秒

瞭解意思嗎? 誤差應該是很小的, 除非你跑了成千上百個 thread

weiclin iT邦高手 4 級 ‧ 2016-05-25 21:46:56 檢舉

那如果你真的跑了成千上百個 thread, 我想你肯定做錯了

因為理論上最佳的狀態是一個 cpu 核心執行一個 thread, 這樣可以避免 context switch 造成的效能消耗

我會推薦你參考 java 的 ExecutorService, 他提供了很好用的 thread pool, 底下是簡單的教學:

http://tutorials.jenkov.com/java-util-concurrent/executorservice.html

OK,感謝你呀~上了一課~

我要發表回答

立即登入回答