我尝试使用fork join框架为填充浮点数的1D数组实现中值过滤器。我已设法按顺序执行此操作并且我的并行版本正在输出值,只是每次运行它输出不同的值时,例如当打印出已过滤数组的第一个元素时,我将得到-0.178966在再次运行之后,我将获得-0.168073,依此类推。我认为这可能是某种竞争条件,或者我在主要课堂上忽视某些事情或做错事。无论哪种方式,我希望你们中的一个人可以帮助我,我是并行编程的新手并且还没有完全理解它,所以请耐心等待。谢谢。 (忽略主类中注释掉的代码)
我的主要课程和其他一些相关代码:
static final ForkJoinPool fjPool = new ForkJoinPool();
static void F(int fs,double[] nums, double[] ans)
{
fjPool.invoke(new TFilter(fs,nums,0,nums.length,ans));
}
public static void main(String[] args)
{
//note program requires user to enter file name, ask for filter size, and
//write to file with name being asked by program.
//Scanner scn = new Scanner(System.in);
// System.out.println("Enter name of file to be read from:");
//String rfn = scn.nextLine();
//System.out.println("Enter name of file to write to:");
//String wfn = scn.nextLine();
//System.out.println("Enter median filter size: ( must be odd and in range [3,21] )");
//int fs = Integer.parseInt(scn.nextLine());
double[] ss = read("sampleinputfile.txt"); //read fills array with input values
double[] a = new double[ss.length];
F(3,ss,a);
System.out.println(a[0]);
}
我的并行课程:
import java.util.*;
import java.util.concurrent.RecursiveAction;
public class TFilter extends RecursiveAction
{
int lo;
int hi;
int fSize;
double [] arr;
double [] ans;
static final int SEQUENTIAL_CUTOFF = 500;
TFilter(int fs, double[] ar, int l, int h, double[] an)
{
this.fSize = fs;
this.arr = ar;
this.lo = l;
this.hi = h;
this.ans = an;
}
public double median(double[] a)
{
Arrays.sort(a);
double m;
if (a.length % 2 == 0)
{
m = ( a[a.length/2] + a[a.length/2 - 1])/2;
}
else
{
m = a[a.length/2];
}
return m;
}
public void MF()
{
double[] Arr = new double[hi-lo];
int cnt = 0;
for (int i = lo; i < hi; i++)
{
Arr[cnt] = arr[i];
cnt++;
}
int m = (Arr.length-fSize)+1;
List<Double> med = new ArrayList<>();
double[] win = new double[fSize];
for (int i = 0; i < m; i++)
{
int c = i;
for (int j = 0; j < fSize; j++)
{
win[j] = Arr[c];
c++;
}
med.add(median(win));
}
int x = (Arr.length-m)/2;
for (int i = 0; i < x; i++) //first boundry points
{
ans[i] = Arr[i];
}
int c = 0;
for (int i = x; i < Arr.length-x; i++)
{
ans[i] = med.get(c);
c++;
}
for (int i = Arr.length-x; i < Arr.length; i++) //last boundry points
{
ans[i] = Arr[i];
}
}
@Override
protected void compute()
{
if((hi-lo) < SEQUENTIAL_CUTOFF)
{
MF();
}
else
{
TFilter left = new TFilter(fSize,arr,lo,(hi+lo)/2,ans);
TFilter right = new TFilter(fSize,arr,(hi+lo)/2,hi,ans);
left.fork();
right.compute();
left.join();
}
}
}