最近在写一个并行程序来解线性方程组,但是发现运行后比串行的速度还慢,而且不止慢一点点.差不多是慢了5倍的样子.想问两个问题:
1.java线程有支持多核吗.JDK1.5
2.可以查看正在运行中的线程是由哪个处理器运行的吗?也很有可能是我的程序写得有问题,我正在检查.不知道各位是不是也碰到过同样的情况,有什么经验可以分享下吗.谢谢啦
1.java线程有支持多核吗.JDK1.5
2.可以查看正在运行中的线程是由哪个处理器运行的吗?也很有可能是我的程序写得有问题,我正在检查.不知道各位是不是也碰到过同样的情况,有什么经验可以分享下吗.谢谢啦
如果在同一时刻,有多个线程并行运行,那jdk里关于现成操作的方法是不是就没用了呢?
public class Matrix {
double matrix[][];
int n;
/**
*构造函数
*根据标志flag的不同初始化U或L
**/
public Matrix(String flag,int n) {
this.n=n;
matrix=new double[n][n];
int i,j,k;
//对U做初始化,上三角的每个元素置-0.0000001代表没有赋值
if(flag.equalsIgnoreCase("u")){
for(i=0;i<n;i++){
for(j=i;j<n;j++){
matrix[i][j]=-0.0000001;
}
}
//对L做初始化,下三角的每个元素置-0.0000001代表没有赋值
}else if(flag.equalsIgnoreCase("l")){
for(i=0;i<n;i++){
for(j=0;j<i+1;j++){
matrix[i][j]=-0.0000001;
}
}
for(j=0;j<n;j++){
matrix[j][j]=1;
}
}
}
//并行计算时使用,达到同步的目的
public synchronized double get(int i,int j){
while(matrix[i][j]==-0.0000001){
try{
this.wait();
}catch(InterruptedException e){
System.out.println(e.getMessage());
}
}
return matrix[i][j];
}
//并行计算时使用,达到同步的目的
public synchronized void set(int i,int j,double value){
this.notify();
matrix[i][j]=value;
}
}
问题在get方法.因为我要检查的是数组中某个单元的值是否符合要求,但是set方法中赋值的单元不一定是get方法中想得到的单元,所以在get方法中需要一直在等待.所以我用了一个循环,我想应该是这个地方占了很多时间.但是怎么解决呢.
matrix[i][j]=value;
this.notify();
} 你贴的代码不够分析的,不知道谁调用了set ,也就是说不知道什么情况下会notify 另外这例子不适合做多线程demo。
this.notify();
这两句的顺序应该没有问题.我把其他代码贴出来大家看看.
除了上面的 Matrix外,还有三个类:CL,CU两个线程,负责进行LU分解,CLU主程序.public class CL implements Runnable{
int n;
double a[][];
Matrix l;
Matrix u;
public CL(int n,double a[][],Matrix l,Matrix u){
this.n=n;
this.a=a;
this.l=l;
this.u=u;
}
public void run(){
System.out.println("CL BEGIN");
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
int k=0;
for(int m=0;m<i;m++){
double temp=u.get(m,i);
k+=l.get(j,m)*temp;
}
double temp2=u.get(i,i);
l.set(j,i,(a[j][i]-k)/temp2);
}
//System.out.println(l.toString());
}
CLU.flagL=true;
System.out.println("CL END");
// System.out.println(l.toString());
}
}
public class CU implements Runnable{
int n;
double a[][];
Matrix l;
Matrix u;
public CU(int n,double a[][],Matrix l,Matrix u){
this.n=n;
this.a=a;
this.l=l;
this.u=u;
}
public void run(){
System.out.println("CU BEGIN");
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
int k=0;
for(int m=0;m<i;m++){
double temp=l.get(i,m);
k+=temp*u.get(m,j);
//Thread.yield();
}
u.set(i,j,a[i][j]-k);
}
//System.out.println(u.toString());
}
CLU.flagU=true;
System.out.println("CU END");
// System.out.println(u.toString());
}
}
class CLU{
double a[][];
Matrix l;
Matrix u;
static boolean flagL;
static boolean flagU;
int n; //线性方程的阶数
public CLU(double matrixA[][]){
this.a=matrixA;
this.n=a.length;
u=new Matrix("u",n);
l=new Matrix("l",n);
}
//并行计算L和U
public void caculateLU(){
CL cu=new CL(n,a,l,u);
CU cl=new CU(n,a,l,u);
Thread tu=new Thread(cu);
Thread tl=new Thread(cl); tu.start();
tl.start(); while(!(flagL&&flagU)){
}
}
//串行计算L和U
/**
*算法,做n次循环,没次循环中先算U的i行,再在U的i行基础上算L的i列
*/
public void caculateLU_s(){
int i,j,k,m;
double temp; for(i=0;i<n;i++){
//计算U的第i行
for(j=i;j<n;j++){
k=0;
for(m=0;m<i;m++){
temp=l.get_s(i,m);
k+=temp*u.get_s(m,j);
}
u.set_s(i,j,a[i][j]-k);
}
//计算L的第i列
for(j=i+1;j<n;j++){
k=0;
for(m=0;m<i;m++){
temp=u.get_s(m,i);
k+=l.get_s(j,m)*temp;
}
double temp1=u.get_s(i,i);
l.set_s(j,i,(a[j][i]-k)/temp1);
}
}
}
public static void main(String a[]){
int n=100;
double matrixa[][]=new double[n][n];
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
matrixa[i][j]=i+j+1;
CLU clu=new CLU(matrixa);
System.out.println(new java.util.Date());
clu.caculateLU();//并行
//clu.caculateLU_s();//串行
System.out.println(new java.util.Date()); System.out.println(clu.x.toString());
}
}
int n;
double a[][];
Matrix l;
Matrix u;
public CL(int n,double a[][],Matrix l,Matrix u){
this.n=n;
this.a=a;
this.l=l;
this.u=u;
}
public void run(){
System.out.println("CL BEGIN");
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
int k=0;
for(int m=0;m<i;m++){
double temp=u.get(m,i);
k+=l.get(j,m)*temp;
}
double temp2=u.get(i,i);
l.set(j,i,(a[j][i]-k)/temp2);
}
//System.out.println(l.toString());
}
CLU.flagL=true;
System.out.println("CL END");
// System.out.println(l.toString());
}
}
Java code
public class CU implements Runnable{
int n;
double a[][];
Matrix l;
Matrix u;
public CU(int n,double a[][],Matrix l,Matrix u){
this.n=n;
this.a=a;
this.l=l;
this.u=u;
}
public void run(){
System.out.println("CU BEGIN");
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
int k=0;
for(int m=0;m<i;m++){
double temp=l.get(i,m);
k+=temp*u.get(m,j);
//Thread.yield();
}
u.set(i,j,a[i][j]-k);
}
//System.out.println(u.toString());
}
CLU.flagU=true;
System.out.println("CU END");
// System.out.println(u.toString());
}
}
Java code
class CLU{
double a[][];
Matrix l;
Matrix u;
static boolean flagL;
static boolean flagU;
int n; //线性方程的阶数
public CLU(double matrixA[][]){
this.a=matrixA;
this.n=a.length;
u=new Matrix("u",n);
l=new Matrix("l",n);
}
//并行计算L和U
public void caculateLU(){
CL cu=new CL(n,a,l,u);
CU cl=new CU(n,a,l,u);
Thread tu=new Thread(cu);
Thread tl=new Thread(cl); tu.start();
tl.start(); while(!(flagL&&flagU)){
}
}
//串行计算L和U
/**
*算法,做n次循环,没次循环中先算U的i行,再在U的i行基础上算L的i列
*/
public void caculateLU_s(){
int i,j,k,m;
double temp; for(i=0;i<n;i++){
//计算U的第i行
for(j=i;j<n;j++){
k=0;
for(m=0;m<i;m++){
temp=l.get_s(i,m);
k+=temp*u.get_s(m,j);
}
u.set_s(i,j,a[i][j]-k);
}
//计算L的第i列
for(j=i+1;j<n;j++){
k=0;
for(m=0;m<i;m++){
temp=u.get_s(m,i);
k+=l.get_s(j,m)*temp;
}
double temp1=u.get_s(i,i);
l.set_s(j,i,(a[j][i]-k)/temp1);
}
}
}
public static void main(String a[]){
int n=100;
double matrixa[][]=new double[n][n];
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
matrixa[i][j]=i+j+1;
CLU clu=new CLU(matrixa);
System.out.println(new java.util.Date());
clu.caculateLU();//并行
//clu.caculateLU_s();//串行
System.out.println(new java.util.Date()); System.out.println(clu.x.toString());
}
}
一种是线程包里有个函数