有没有人有一个关于如何从 Java 17 调用 C 函数(包括创建 C 库以及如何设置 MethodHandle)的简单示例?
https://openjdk.java.net/jeps/412上的 JEP 描述确实有一个示例,但我一直在努力理解它。
我认为可以使用巴拿马项目(https://jdk.java.net/panama/)jextract来实现,但由于该功能已包含在 JDK 中,因此我不想使用巴拿马。
我正在测试OpenJDK Panama Vector API jdk.incubator.vector 并在亚马逊 c5.4xlarge 实例上进行了测试。但在每种情况下,简单展开的矢量点积都无法执行 Vector API 代码。
我的问题是:为什么我无法获得如Richard Startin 的博客中所示的性能提升。同样的性能提升也在这次会议meetup中被英特尔人讨论过。有什么不见了?
JMH 基准测试结果:
Benchmark (size) Mode Cnt Score Error Units
FloatVector256DotProduct.unrolled 1048576 thrpt 25 2440.726 ? 21.372 ops/s
FloatVector256DotProduct.vanilla 1048576 thrpt 25 807.721 ? 0.084 ops/s
FloatVector256DotProduct.vector 1048576 thrpt 25 909.977 ? 6.542 ops/s
FloatVector256DotProduct.vectorUnrolled 1048576 thrpt 25 887.422 ? 5.557 ops/s
FloatVector256DotProduct.vectorfma 1048576 thrpt 25 916.955 ? 4.652 ops/s
FloatVector256DotProduct.vectorfmaUnrolled 1048576 thrpt 25 877.569 ? 1.451 ops/s
JavaDocExample.simpleMultiply 1048576 thrpt …
Run Code Online (Sandbox Code Playgroud) 我正在试验Hunspell以及如何使用Java 项目巴拿马(Build 19-panama+1-13 (2022/1/18))与其交互。我能够完成一些初步测试,例如创建一个handle to Hunspell
并随后使用它来执行拼写检查。我现在正在尝试一些更复杂的事情,让 Hunspell 给我suggestions
一个字典中没有的单词。这是我现在的代码:
public class HelloHun {
public static void main(String[] args) {
MemoryAddress hunspellHandle = null;
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
var allocator = SegmentAllocator.nativeAllocator(scope);
// Point it to US english dictionary and (so called) affix file
// Note #1: it is possible to add words to the dictionary if you like
// Note #2: it is possible to have separate/individual dictionaries and affix files …
Run Code Online (Sandbox Code Playgroud) 我最近一直在读巴拿马项目.
我知道它将成为JNI的下一代替代品 - 它将允许Java开发人员使用Java在本机层上进行编码(这是令人惊叹的恕我直言).
从我所看到的jnr-posix看,用法很简单,例如:
public class FileTest {
private static POSIX posix;
@BeforeClass
public static void setUpClass() throws Exception {
posix = POSIXFactory.getPOSIX(new DummyPOSIXHandler(), true);
}
@Test
public void utimesTest() throws Throwable {
// FIXME: On Windows this is working but providing wrong numbers and therefore getting wrong results.
if (!Platform.IS_WINDOWS) {
File f = File.createTempFile("utimes", null);
int rval = posix.utimes(f.getAbsolutePath(), new long[]{800, 200}, new long[]{900, 300});
assertEquals("utimes did not return 0", 0, rval);
FileStat …
Run Code Online (Sandbox Code Playgroud) 我在巴拿马遵循了 Java 中 SIMD 的英特尔教程 。我想对数组做一些简单的操作:
这里是网站的标量和向量循环:
public static void scalarComputation(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (a[i] * a[i] + b[i] * b[i]) * - 1.0f;
}
}
public static void vectorComputation(float[] a, float[] b, float[] c) {
int i = 0;
for (; i < (a.length & ~(species.length() - 1));
i += species.length()) {
FloatVector<Shapes.S256Bit> va = speciesFloat.fromArray(a, i);
FloatVector<Shapes.S256Bit> vb = speciesFloat.fromArray(b, i); …
Run Code Online (Sandbox Code Playgroud) 我正在尝试测试 Java 21 的外部函数和内存功能。这是我的代码:
\npublic static void main(String[] args) {\n // 1. Find foreign function on the C library path\n Linker linker = Linker.nativeLinker();\n SymbolLookup stdlib = linker.defaultLookup();\n MethodHandle radixsort = linker.downcallHandle(stdlib.find("radixsort").orElseThrow(), FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_CHAR));\n // 2. Allocate on-heap memory to store four strings\n String[] javaStrings = {"mouse", "cat", "dog", "car"};\n\n // 3. Use try-with-resources to manage the lifetime of off-heap memory\n try (Arena offHeap = Arena.ofConfined()) {\n // 4. Allocate a region of off-heap memory to store …
Run Code Online (Sandbox Code Playgroud) 我想使用巴拿马项目中的外部函数接口来访问 Java19 中的 C 库。C 接口非常简单:
typedef struct {
int len;
char name[100];
} ent;
ent* foo();
Run Code Online (Sandbox Code Playgroud)
调用时,函数 foo 返回指向 的指针struct ent
,其中len
指示字符串的大小name
。
对应的Java端是:
private static final MemoryLayout ENT_LAYOUT = MemoryLayout.structLayout(
JAVA_INT.withName("len"),
MemoryLayout.sequenceLayout(100, ValueLayout.JAVA_BYTE).withName("name")
);
Run Code Online (Sandbox Code Playgroud)
为了方便访问,我想使用VarHandle
:
private static final VarHandle VH_ENT_LEN = ENT_LAYOUT.varHandle(groupElement("len"));
Run Code Online (Sandbox Code Playgroud)
以及后来
int len = (int)VH_ENT_LEN.get(segment);
String name = segment.asSlice(ENT_LAYOUT.byteOffset(groupElement("name")), len).getUtf8String(0);
Run Code Online (Sandbox Code Playgroud)
这仍然有点混乱。
我天真的期望解决方案应该是这样的:
private static final VarHandle VH_ENT_NAME = ENT_LAYOUT.varHandle(groupElement("name"), sequenceElement());
byte[] nameRaw = (byte[])VH_ENT_NAME.get(segment);
Run Code Online (Sandbox Code Playgroud)
但是我得到:
java.lang.RuntimeException: java.lang.invoke.WrongMethodTypeException:
cannot convert MethodHandle(VarHandle,MemorySegment,long)byte …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Java 19 的巴拿马项目(外部函数接口)使用以下代码来读取 Windows 10 上的当前目录(作为一个简单的示例)。这是我的代码的开始:
final Linker linker = Linker.nativeLinker();
final SymbolLookup linkerLookup = linker.defaultLookup();
final SymbolLookup systemLookup = SymbolLookup.loaderLookup();
final SymbolLookup symbolLookup = name -> systemLookup.lookup(name)
.or(() -> linkerLookup.lookup(name));
final MemorySegment addr = symbolLookup.lookup("GetCurrentDirectory")
.orElse(null);
...
Run Code Online (Sandbox Code Playgroud)
问题是,当调试时addr
,null
看起来找不到这个名称的方法。我是否需要以某种方式告诉查找应该在哪个 DLL 中查找此函数(对于printf
对此进行的测试来说没有必要)?
在使用MemoryLayout::varHandle构造varHandle时,我传入了一个自组装的Object数组来实现构造MemorySegment的公共方法。但是,我发现它似乎阻止我使用对象数组而不是可变数组。
代码片段如下。
public static MemorySegment buildMemorySegment(Object object, MemorySegment memorySegment, MemoryLayout originMemoryLayout, MemoryLayout memoryLayout, List<PathElement> pathElements, List<Object> indexParams) throws NoSuchFieldException, IllegalAccessException {
Class<?> aClass = object.getClass();
if (memoryLayout instanceof SequenceLayout sequenceLayout) {
pathElements.add(PathElement.sequenceElement());
for (int i = 0; i < sequenceLayout.elementCount(); i++) {
Object[] array;
if (Collection.class.isAssignableFrom(aClass)) {
assert object instanceof Collection<?>;
Collection<?> collection = (Collection<?>) object;
array = collection.toArray();
} else {
assert object instanceof Object[];
array = ((Object[]) object);
}
Object o = array[i];
indexParams.add((long) i);
buildMemorySegment(o, memorySegment, originMemoryLayout, …
Run Code Online (Sandbox Code Playgroud)