java - Jni native C++在android中并不比java快
问题描述
我有一个在java中处理大浮点数组的代码,但它太慢了。所以我尝试使用Jni原生C++来提高性能和处理速度,可惜还是太慢了。甚至比java版本慢。这是我的部分代码,您可以告诉我如何改进它。
在android java中:
private float[] nonMaxSuppression_java( float[] map,int w1,int w2,int w3, int window) {
int size = w1*w2*w3;
float[] original = new float[w1*w2*w3];
for(int d =0; d<w3;d++) {
for (int i = 0; i < w1; i++) {
for (int j = 0; j <w2; j++) {
float max = -99;
float current = map[d+w3*(j+w2*i)];
for (int row_offset = 0; row_offset < window; row_offset++) {
for (int col_offset = 0; col_offset < window; col_offset++) {
int row_index = i + row_offset - window / 2;
int col_index = j + col_offset - window / 2;
if (row_index < w1 && col_index < w2 && row_index >= 0 && col_index >= 0) {
float a = map[d+w3*(col_index+w2*row_index)];
if(map[d+w3*(col_index+w2*row_index)] > max) {
max = map[d+w3*(col_index+w2*row_index)];
}
}
}
}
if (current != max) {
original[d + w3 * (j + w2 * i)] = 0;
} else {
original[d + w3 * (j + w2 * i)] = map[d+w3*(j+w2*i)];
}
}
}
}
return original;
}
在本机 C++ 中:
extern "C"
JNIEXPORT jfloatArray JNICALL
Java_com_asus_poseestimator_JNIUtils_nonMaxSuppression(JNIEnv *env, jobject instance, jfloatArray map_,jint w1,jint w2,jint w3, jint window) {
jfloat *map = env->GetFloatArrayElements(map_, 0);
int size = w1*w2*w3
;
jfloatArray result = env->NewFloatArray(size);
float *original = new float[w1*w2*w3];
for(int d =0; d<w3;d++) {
for (int i = 0; i < w1; i++) {
for (int j = 0; j <w2; j++) {
float max = -99;
float current = MAP(i,j,d);
for (int row_offset = 0; row_offset < window; row_offset++) {
for (int col_offset = 0; col_offset < window; col_offset++) {
int row_index = i + row_offset - window / 2;
int col_index = j + col_offset - window / 2;
if (row_index < w1 && col_index < w2 && row_index >= 0 && col_index >= 0) {
if(MAP(row_index,col_index,d) > max) {
max = MAP(row_index, col_index, d);
}
}
}
}
if (current != max) {
original[d + w3 * (j + w2 * i)] = 0;
} else {
original[d + w3 * (j + w2 * i)] = MAP(i, j, d);
}
}
}
}
env->SetFloatArrayRegion(result, 0, size, original);
env->ReleaseFloatArrayElements(map_,map,0);
delete [] original;
return result;
}
我使用 Cmake 构建 JNI
cmake {
// for neon optimization:
abiFilters "armeabi-v7a"
cppFlags "-DCMAKE_BUILD_TYPE:STRING=Release -DHAVE_NEON -O3 -Wno-parentheses -mfpu=neon -mfloat-abi=softfp -march=armv7-a"
}
为什么 java 运行这个函数比原生 C++ 更快?
解决方案
改进这两个版本的明显方法是使用顺序数组访问。您的循环变量是(从外到内)d,i,j
,但您的循环索引是[d + w3*j + w3*w2*i]
. 要按顺序访问数组,[0]
后面应该跟[1]
which 表示d
应该是内部循环变量,而不是外部循环变量。
推荐阅读
- angular7 - Angular 6 无法使用本地参考禁用启用输入
- php - 使用 mysql_data_seek 时 PHP Extra 1 空行
- python - 如何在 Python 中使用 Paramiko 时使 EllipticCurvePublicNumbers.encode_point CryptographyDeprecationWarning 静音
- excel - Excel 条件格式 - 间接地址公式
- javascript - 如何不将点击事件传递给响应的孩子?
- tensorflow - Keras:带有 predict_generator 的混淆矩阵
- php - Laravel / Blade:标签/空格未正确包含
- c# - 为什么我的 Unity 项目会失去与 Git 的脚本和资产的连接?
- javascript - 为什么 SpeechSynthesisUtterance 有时不会在基于 Chromium 的浏览器中触发“结束”事件?
- android - 添加滑翔依赖项时出现问题