6

我想优化 InputStream 的读取,然后我认为最好有一个 RAM 页面大小的 byte[] 缓冲区。

有没有一种方法(可能是静态的)来知道它的大小?

编辑:

最后我成功使用了NDK和JNI,我用C写了以下代码:

#include <jni.h>
#include <unistd.h>

jlong Java_it_masmil_tests_TestsActivity_pageSize(JNIEnv* env, jobject javaThis) {
    return sysconf(_SC_PAGE_SIZE);
}

在哪里:

  • it.masmil.tests 是包名
  • TestsActivity 是类名
  • pageSize 是方法名
  • env 和 java 这是两个强制参数(在某些场合有用)

我用 NDK 编译了那个文件,然后我用 Java 编写了以下代码:

static {
    System.loadLibrary("clibrary");
}
private native long pageSize();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    long page = pageSize();
}

在哪里:

  • clibrary 是我用 NDK 创建的库的名称
  • pageSize 是 C 文件中声明的方法的名称
4

3 回答 3

8

页面大小由 Linux(内核)定义,您可以通过 JNI 通过调用 libc(仿生)来获取它sysconf(_SC_PAGESIZE)。由于 Android 在 Linux 上运行并且主要在 ARM 系统上运行,因此您可以假设 4k 页面大小。

#include <unistd.h>
long sz = sysconf(_SC_PAGESIZE);

但是,您不能真正轻松地从 Java/C 中获得这种对齐方式。这意味着即使您要求 4k 块,也没有人保证会与 4k 对齐。

如果您在 Linux 上需要 4k 对齐的块,您应该使用保证页面大小对齐的mmap 。

于 2012-11-12T21:44:33.837 回答
1

您通常可以假设页面大小为 4KB 或更大(可以处理较小页面大小的 MMU 实际上已绝迹)。此外,如果您无法将缓冲区对齐到确切的页面边界,它很可能仍会跨越两个页面。

最后,所有这些努力都完全白费了——如果 MMU 遭受一两次页面丢失,实际 I/O 成本将超过许多数量级。你甚至不可能收回增加的初始化成本,更不用说你花在实现它上的所有时间了。

你做了一个过分热心的优化工作的完美例子,如果你只是分析你的应用程序并在最常调用的方法中减少一两个周期,你可能会花费所有时间来获得更大的回报(例如)。

于 2013-04-27T13:59:07.427 回答
-1

很难相信添加 JNI 等真的会收回成本。像其他人一样使用 4096 或 8192。

于 2013-04-27T10:57:06.807 回答