JNI错误对齐阵列的性能方面 当通过JNI从java传递C++到C++时,使用C++内联(或ASM内联)提高性能的三个障碍。

JNI错误对齐阵列的性能方面 当通过JNI从java传递C++到C++时,使用C++内联(或ASM内联)提高性能的三个障碍。,java,c++,java-native-interface,memory-alignment,Java,C++,Java Native Interface,Memory Alignment,1) JNI调用有一个开销(正如预期的那样,从20个周期到100个周期) 2) 数组被传递为错误对齐(需要32B或16B对齐),因此需要移动整个两个数组以使它们对齐,然后在最后移回原来的位置 3) 创建一个新的数组以将结果发送到java(例如:向量乘法C=a*B),如果我们从java提供一个数组,它也会错误对齐!所以我们需要在C++中创建一个新的对齐数组,这会减慢整个进程。 我们可以制作一个更大的数组来连接两个数组,而不是移动两个数组,但这也会很慢 如果我们只能使用(更少的数据,更多的计算)结构

1) JNI调用有一个开销(正如预期的那样,从20个周期到100个周期)

2) 数组被传递为错误对齐(需要32B或16B对齐),因此需要移动整个两个数组以使它们对齐,然后在最后移回原来的位置

3) 创建一个新的数组以将结果发送到java(例如:向量乘法C=a*B),如果我们从java提供一个数组,它也会错误对齐!所以我们需要在C++中创建一个新的对齐数组,这会减慢整个进程。 我们可以制作一个更大的数组来连接两个数组,而不是移动两个数组,但这也会很慢

如果我们只能使用(更少的数据,更多的计算)结构,那么使用JNI来提高性能有什么意义

--在JNI中使用纯c++(无内在特性)只比纯java快10%-20%

--使用内部函数将乘法/秒增加了%70,但缓慢的数组复制仍然有效。java将其数组移动到32B对齐位置的可能性只有%50

--使用
GetPrimitiveArrayCritical
而不是
GetArrayElements()
使大向量的点积(256k个元素)又获得了%250的性能。这一定是在JNI工作和非拷贝访问时关闭gc的结果

--在我的机器上,使用直接字节缓冲区而不是基本数组快了%40(在纯java上是5x-6x)。还允许我在本机地址选择器的帮助下选择一个自定义偏移量,使其与32B对齐。因此,我们可以有一个32B对齐的直接缓冲区子集(在“C”空间中),但不能有一个基本数组

--将一个大缓冲区分成8个部分和8个java线程,使计算速度比单个directbytebuffer快了40%(这可能接近我的ram限制,因为我只对每个元素执行一次乘法)

最新案例与java的单线程循环展开乘法的总速度比接近6倍,在我应用多线程处理后,对于这个特定的点积,它增加到8倍(不是因为内存带宽,不是计算限制)

为了克服上述三个困难,您可以添加哪些内容


<> P> <强>我们如何通过java将C++的32个数组排列成JNI?

使用NiO缓冲区是一个选项吗?它们能按需要排列吗?我是JNI的新手,从来没有使用过它们,但是DOCS说它们可以。请你给我一个链接好吗?