我试图从Java调用C函数。 C函数使用openmp并行for循环。但是,在程序完成后,结果显示只使用了一个线程。所以,我想知道将openmp与JNI一起使用是否可行。
由于
以下是我的clang信息和makefile的内容:
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 :(得分:0)
当然,您可以在JNI方法中运行OpenMP。请观看以下示例(包括JNI代码[Java和C-counter-side]和Makefile)。它使用几个线程通过近似计算pi,在计算之前,每个线程在屏幕上标识自己。
您可能需要调整它,将CC和JDK变量更改为您的环境以及一些Linux / gcc vs 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