From 1f9fdf3814f08d782befddee7c2455b5b962fa12 Mon Sep 17 00:00:00 2001 From: Alice Wang Date: Fri, 14 Oct 2022 15:14:00 +0000 Subject: [PATCH] [benchmark] Add benchmarks for authfs seq/rand write This CL adds benchmarks for authfs remote write in sequential and random modes. Test: atest AuthFsBenchmarks Bug: 236123069 Change-Id: Ib13aa46a0e8bf17f89d80ff88d6dc1ca02582be2 --- .../src/com/android/fs/AuthFsBenchmarks.java | 31 +++++++++++++++++-- .../src/com/android/fs/AuthFsTestRule.java | 2 +- authfs/tests/measure_io.cpp | 16 +++++++--- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/authfs/tests/java/src/com/android/fs/AuthFsBenchmarks.java b/authfs/tests/java/src/com/android/fs/AuthFsBenchmarks.java index fb8c0cc8..f84785b5 100644 --- a/authfs/tests/java/src/com/android/fs/AuthFsBenchmarks.java +++ b/authfs/tests/java/src/com/android/fs/AuthFsBenchmarks.java @@ -47,7 +47,6 @@ import java.util.Map; @RunWith(DeviceJUnit4ClassRunner.class) public class AuthFsBenchmarks extends BaseHostJUnit4Test { private static final int TRIAL_COUNT = 5; - private static final int FILE_SIZE_IN_MB = 4; /** Name of the measure_io binary on host. */ private static final String MEASURE_IO_BIN_NAME = "measure_io"; @@ -92,6 +91,16 @@ public class AuthFsBenchmarks extends BaseHostJUnit4Test { readRemoteFile("rand"); } + @Test + public void seqWriteRemoteFile() throws Exception { + writeRemoteFile("seq"); + } + + @Test + public void randWriteRemoteFile() throws Exception { + writeRemoteFile("rand"); + } + private void readRemoteFile(String mode) throws DeviceNotAvailableException { pushMeasureIoBinToMicrodroid(); // Cache the file in memory for the host. @@ -100,7 +109,8 @@ public class AuthFsBenchmarks extends BaseHostJUnit4Test { .run("cat " + mAuthFsTestRule.TEST_DIR + "/input.4m > /dev/null"); String filePath = mAuthFsTestRule.MOUNT_DIR + "/3"; - String cmd = MEASURE_IO_BIN_PATH + " " + filePath + " " + FILE_SIZE_IN_MB + " " + mode; + int fileSizeMb = 4; + String cmd = MEASURE_IO_BIN_PATH + " " + filePath + " " + fileSizeMb + " " + mode + " r"; List rates = new ArrayList<>(TRIAL_COUNT); for (int i = 0; i < TRIAL_COUNT + 1; ++i) { mAuthFsTestRule.runFdServerOnAndroid( @@ -113,6 +123,23 @@ public class AuthFsBenchmarks extends BaseHostJUnit4Test { reportMetrics(rates, mode + "_read", "mb_per_sec"); } + private void writeRemoteFile(String mode) throws DeviceNotAvailableException { + pushMeasureIoBinToMicrodroid(); + String filePath = mAuthFsTestRule.MOUNT_DIR + "/5"; + int fileSizeMb = 8; + String cmd = MEASURE_IO_BIN_PATH + " " + filePath + " " + fileSizeMb + " " + mode + " w"; + List rates = new ArrayList<>(TRIAL_COUNT); + for (int i = 0; i < TRIAL_COUNT + 1; ++i) { + mAuthFsTestRule.runFdServerOnAndroid( + "--open-rw 5:" + mAuthFsTestRule.TEST_OUTPUT_DIR + "/out.file", "--rw-fds 5"); + mAuthFsTestRule.runAuthFsOnMicrodroid("--remote-new-rw-file 5"); + + String rate = mAuthFsTestRule.getMicrodroid().run(cmd); + rates.add(Double.parseDouble(rate)); + } + reportMetrics(rates, mode + "_write", "mb_per_sec"); + } + private void pushMeasureIoBinToMicrodroid() throws DeviceNotAvailableException { File measureReadBin = mAuthFsTestRule.findTestFile(getBuild(), MEASURE_IO_BIN_NAME); assertThat(measureReadBin.exists()).isTrue(); diff --git a/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java b/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java index ebeac4ff..045ecc08 100644 --- a/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java +++ b/authfs/tests/java/src/com/android/fs/AuthFsTestRule.java @@ -62,7 +62,7 @@ public class AuthFsTestRule extends TestLogData { private static final String TEST_APK_NAME = "MicrodroidTestApp.apk"; /** Output directory where the test can generate output on Android */ - private static final String TEST_OUTPUT_DIR = "/data/local/tmp/authfs/output_dir"; + static final String TEST_OUTPUT_DIR = "/data/local/tmp/authfs/output_dir"; /** Mount point of authfs on Microdroid during the test */ static final String MOUNT_DIR = "/data/local/tmp/mnt"; diff --git a/authfs/tests/measure_io.cpp b/authfs/tests/measure_io.cpp index e9548ae2..e1f2fb87 100644 --- a/authfs/tests/measure_io.cpp +++ b/authfs/tests/measure_io.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -32,11 +33,13 @@ constexpr int kBlockSizeBytes = 4096; constexpr int kNumBytesPerMB = 1024 * 1024; int main(int argc, const char *argv[]) { - if (argc != 4 || !(strcmp(argv[3], "rand") == 0 || strcmp(argv[3], "seq") == 0)) { - errx(EXIT_FAILURE, "Usage: %s ", argv[0]); + if (argc != 5 || !(strcmp(argv[3], "rand") == 0 || strcmp(argv[3], "seq") == 0) || + !(strcmp(argv[4], "r") == 0 || strcmp(argv[4], "w") == 0)) { + errx(EXIT_FAILURE, "Usage: %s ", argv[0]); } int file_size_mb = std::stoi(argv[2]); bool is_rand = (strcmp(argv[3], "rand") == 0); + bool is_read = (strcmp(argv[4], "r") == 0); const int block_count = file_size_mb * kNumBytesPerMB / kBlockSizeBytes; std::vector offsets(block_count); for (auto i = 0; i < block_count; ++i) { @@ -46,7 +49,7 @@ int main(int argc, const char *argv[]) { std::mt19937 rd{std::random_device{}()}; std::shuffle(offsets.begin(), offsets.end(), rd); } - unique_fd fd(open(argv[1], O_RDONLY | O_CLOEXEC)); + unique_fd fd(open(argv[1], (is_read ? O_RDONLY : O_WRONLY) | O_CLOEXEC)); if (fd.get() == -1) { errx(EXIT_FAILURE, "failed to open file: %s", argv[1]); } @@ -54,13 +57,18 @@ int main(int argc, const char *argv[]) { char buf[kBlockSizeBytes]; clock_t start = clock(); for (auto i = 0; i < block_count; ++i) { - auto bytes = pread(fd, buf, kBlockSizeBytes, offsets[i]); + auto bytes = is_read ? pread(fd, buf, kBlockSizeBytes, offsets[i]) + : pwrite(fd, buf, kBlockSizeBytes, offsets[i]); if (bytes == 0) { errx(EXIT_FAILURE, "unexpected end of file"); } else if (bytes == -1) { errx(EXIT_FAILURE, "failed to read"); } } + if (!is_read) { + // Writes all the buffered modifications to the open file. + assert(syncfs(fd) == 0); + } double elapsed_seconds = ((double)clock() - start) / CLOCKS_PER_SEC; double rate = (double)file_size_mb / elapsed_seconds; std::cout << std::setprecision(12) << rate << std::endl;