2015-09-28 121 views
3

我有一个很长的双重嵌套的for循环来进行许多试验。我想同时做到这一点,因为这些试验是相互独立的。我如何在Java中像使用C++的OpenMP一样高效地实现它?我将在具有64个处理器的节点上运行此操作,因此我希望每个内核都可以采取一项措施。在Java中for循环的并行化

相关代码:

//I want each measure to perform the doubly nested loop at the same time. 

for (int i : measures) { 

    for (int j = 0; j < N; j++) { 
    for (int k = 0; k < N; k++) { 
    array[i*N*N + j*N + k] = someFunc(i,j,k); 
    } 
    } 

} 

编辑:问题仍然没有解决:

//sim is a 1D array of type double 
//gM is an array of type SMconf 
//gene[foo].annot is a LinkedHashSet of URIs. 
//Javadoc http://www.semantic-measures-library.org/sml/docs/apidocs/ 

Arrays.parallelSetAll(sim, i -> { 
    try { 
     engine.compare(gM[i/(N*N)], gene[(i/N)%N].annot, gene[i % N].annot); 
    } 
    catch (SLIB_Ex_Critic ex) { 
     Logger.getLogger(Exp2.class.getName()).log(Level.SEVERE, null, ex); 
    } 
}); 

错误:

enter image description here

+0

了解线程:https://docs.oracle.com/javase/tutorial/essential/concurrency/ – Michael

+1

你可以尝试使用[并行流](https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html#executing_streams_in_parallel) - 尽管您可能需要更改'someFunc'签名以直接接受数组项,而不是其数组项在阵列中的位置。 –

回答

0
int N=5; 
    int array[]=new int[200]; 
    int [] measures={1,2,3,4,5}; 

    Arrays.stream(measures).parallel().forEach(i->{ 
     IntStream.range(0, N).parallel().forEach(j->{ 
      IntStream.range(0, N).parallel().forEach(k->{ 
       array[i*N*N+j*N + k]= someFunc(i,j,k); 
      }); 
     }); 
    }); 


    Arrays.stream(array).forEach(System.out::println); 

考虑measures是一个数组而不是ArrayList。在写array[]时,您可能需要锁。 我希望你没有使用array作为变量名称。

+0

如果度量不是int数组,而是Measure类的对象数组呢? – henri

+0

如果'measure'不是int,那么你的代码对于(int i:度量)''运行怎么样?另外,为什么在设置'array [i * N * N + j * N + k]'时跳过索引? – pallavt

+0

对不起,我在哪里跳过索引? – henri

0

也许这将是有效的收起使用Java-8方法Arrays.parallelSetAll

Arrays.parallelSetAll(array, idx -> someFunc(idx/(N*N), (idx/N)%N, idx % N)); 

这将设置数组元素独立地并联。虽然你可能有划分的开销,但它可能比创建嵌套并行流的开销小得多,就像在@pallavt答案中一样。虽然它可能取决于问题的大小。

如果您someFunc抛出checked异常,重新抛出它作为一个未经检查:

Arrays.parallelSetAll(array, idx -> { 
    try { 
     return someFunc(idx/(N*N), (idx/N)%N, idx % N); 
    } 
    catch(MyCheckedException ex) { 
     throw new RuntimeException(ex); 
    } 
}); 
+0

如果生成器函数抛出异常。它发生在我身上,Netbeans默认的try catch在parallelSetall函数中不起作用。 – henri

+0

@henri编辑了答案,以显示如何处理检查的异常。通常在Java-8中,您应该更喜欢无处不在的未检查异常。 –

+0

非常感谢Tagir。我再次尝试,但它表示“lamdba表达式中的返回类型错误,缺少返回值。” – henri