2015-10-28 71 views
0

我想從Java調用C函數。 C函數使用openmp與for循環並行。但是,程序結束後,結果顯示只使用一個線程。所以,我想知道用JNI使用openmp是否可行。JNI與openmp

感謝

下面是我的鐺信息和生成文件的內容:

clang version 3.5.0 
Target: x86_64-apple-darwin15.0.0 
Thread model: posix 


CC = gcc 
CLANG = clang-omp 
CFLAGS = -c -Wall -fPIC -std=c11 
OMP = -fopenmp 
LIBFLAG = -dynamiclib 
INCPATH = -I/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/include -I/usr/local/Cellar/libiomp/20150701/include/libiomp -I/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/include/darwin -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers 
LIBPATH = -L./ -L/usr/local/Cellar/libiomp/20150701/lib -lepanet -liomp5 
all: library 

library: *.o 
    $(CC) $(LIBFLAG) $(OMP) -o libJNIFitness.jnilib *.o 

*.o: *.c 
    $(CC) $(OMP) $(CFLAGS) $(INCPATH) *.c 

clean: 
    rm *.o libJNIFitness.jnilib 
+0

是的,我這樣做[cholmod式的Java(http://stackoverflow.com/questions/17046585/cholmod-in-java/30526005#30526005 )。 –

+0

什麼操作系統,什麼編譯器,你使用什麼編譯器選項,你的硬件是什麼? –

+0

它是OSX EI Capitan,所以編譯器是LLVM,我用clang-omp編譯C代碼。 – Juneyee

回答

0

當然你也可以在JNI方法中運行的OpenMP。觀看下面的例子(其中包括JNI代碼[Java和C-counter-side]和Makefile)。它通過使用幾個線程的近似計算pi,並在計算每個線程在屏幕上標識自身之前計算pi。

您可能需要修改它以將CC和JDK變量更改爲您的環境以及一些Linux/gcc與MacOsX/clang標誌(例如將-fPIC -DPIC更改爲-dynamiclib等)。然後,你可以通過執行運行它:

make run 

和輸出以下

LD_LIBRARY_PATH=. JNItest 
within Java_JNItest_CalculatePi 
Java_JNItest_calculatepi: I'm thread 0 out of 4 
Java_JNItest_calculatepi: I'm thread 2 out of 4 
Java_JNItest_calculatepi: I'm thread 1 out of 4 
Java_JNItest_calculatepi: I'm thread 3 out of 4 
returning to Java... 
In Java, the value of pi is 3.1415926535896825 

文件JNItest.java

public class JNItest 
{ 
    static { System.loadLibrary("pi"); } 

    public static native double CalculatePi (long nsteps); 

    public static void main(String args[]) 
    { 
     System.out.println ("In Java, the value of pi is " + 
      new JNItest().CalculatePi(100_000_000)); 
    } 
} 

文件pi.c

#include <stdio.h> 
#include <JNItest.h> 

JNIEXPORT jdouble JNICALL Java_JNItest_CalculatePi 
    (JNIEnv * env, jclass jc, jlong nsteps) 
{ 
    jdouble h, area, x; 

    printf ("within Java_JNItest_CalculatePi\n"); 

    h = 1.0/(jdouble) nsteps; 
    area = 0.0; 
    #pragma omp parallel private(x) 
    { 
     int i; 
     printf ("Java_JNItest_calculatepi: I'm thread %d out of %d\n", 
      omp_get_thread_num(), omp_get_num_threads()); 

     #pragma omp for reduction(+:area) 
     for (i = 1; i <= nsteps; i++) 
     { 
      x = h * ((double)i - 0.5); 
      area += (4.0/(1.0 + x*x)); 
     } 
    } 

    printf ("returning to Java...\n"); 

    return h * area; 
} 

文件的makefile

all: JNItest.class libpi.so 

CC=gcc 
JDK=/usr/lib/jvm/java-7-openjdk-amd64 

JNItest.class: JNItest.java 
    $(JDK)/bin/javac JNItest.java 

JNItest.h: JNItest.java 
    $(JDK)/bin/javah JNItest 

libpi.so: JNItest.h 
    $(CC) -fopenmp -fPIC -DPIC pi.c -I. -I$(JDK)/include -shared -o libpi.so 

clean: 
    rm libpi.so JNItest.h JNItest.class 

run: JNItest.class libpi.so 
    LD_LIBRARY_PATH=$(PWD):$(LD_LIBRARY_PATH) $(JDK)/bin/java JNItest