我创建了一个简单的顺序java程序,它使用两种不同的方法(math.pow()和Fast Inverse Square Root)计算数字的平方根,以比较结果的准确性和完成时间。现在我需要并行化这个任务,这样一个线程使用math.pow计算逆平方根,另一个线程使用FISR计算它。我不确定如何解决这个问题,因为我看过的每个多线程示例都有两个线程处理单个问题的两半,而不仅仅是运行单独的任务。我的源代码如下:
package paralleltask;
public class ParallelTask {
public static void main(String[] args) {
System.out.println("Please enter the value:");
Scanner userInputScanner = new Scanner(System.in);
int userIn = userInputScanner.nextInt();
long totalStart = System.nanoTime();
long powStart = System.nanoTime();
double testNum = Math.pow(userIn, -1.0/2);
long powEnd = System.nanoTime();
long powDuration = powEnd - powStart;
long FISRStart = System.nanoTime();
float xhalf = 0.5f*userIn;
int i = Float.floatToIntBits(userIn);
i = 0x5f3759df - (i>>1);
Float x = Float.intBitsToFloat(i);
x = x*(1.5f - xhalf*x*x);
long FISREnd = System.nanoTime();
long totalEnd = System.nanoTime();
long totalDuration = totalEnd - totalStart;
long FISRDuration = FISREnd - FISRStart;
String testNumString = String.valueOf(testNum);
String FISR = String.valueOf(x);
System.out.println("The inverse square root using the math.pow() function is:");
System.out.println(testNumString);
System.out.println("It took " + powDuration + " milliseconds to complete");
System.out.println("The inverse square root using the FISR function is:");
System.out.println(FISR);
System.out.println("It took " + FISRDuration + " milliseconds to complete");
if (testNum > x) {
System.out.println("The FISR approximation was " + (testNum - x) + " smaller than the math.pow() value.");
}
if (testNum < x) {
System.out.println("The FISR approximation was " + (x - testNum) + " larger than the math.pow() value.");
}
System.out.println("The FISR function completed " + (powDuration - FISRDuration) + " milliseconds faster than math.pow");
System.out.println("The total completion time was " + totalDuration + " milliseconds.");
}
}
答案 0 :(得分:3)
我不会将其称为并行化,而是运行两个并发任务(因为您不能使一个计算在多个线程中运行以使其更快,但在单独的线程中运行两个单独的计算) 。如果您想同时运行,可以使用Executor
。
首先,我会重构代码,将两个计算作为一个单独的任务:
public class MathPowCalculation implements Callable<Double> {
private final int input;
public MatPowCalculation(int input) {
this.input = input;
}
@Override
public Double call() throws Exception {
// your calculation and time measurement and logging
return result;
}
}
与第二种算法相似。
然后,您可以同时启动两个计算并接收第一个可用结果:
int input = ...;
ExecutorService executor = Executors.newFixedThreadPool(2);
List<Future<Double>> results = executor.invokeAll(Arrays.asList(new MathPowCalculation(input), new FISRCalculation(input)));
for (Future<Double> result : results) {
Double value = result.get();
// do something with result value
}
executor.shutdown();
您也可以查看ExecutorCompletionService
,它可能会使您的代码更简单。
但是,正如评论中提到的其他人一样,您无法获得可靠的结果。微基准测试(JVM JIT优化等)有一个完整的科学,如果你想获得有用的结果,你需要为此目的使用一个框架。