Add musl benchmarks.
Test: Unit tests.
Change-Id: Ifb2911825f84b95fe64a803bfabd32fb81210eae
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index fae6f20..93f62cf 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -35,6 +35,7 @@
"string_benchmark.cpp",
"time_benchmark.cpp",
"unistd_benchmark.cpp",
+ "stdlib_benchmark.cpp",
],
shared_libs: ["libtinyxml2"],
static_libs: [
diff --git a/benchmarks/bionic_benchmarks.cpp b/benchmarks/bionic_benchmarks.cpp
index 7f91b74..ed5460f 100644
--- a/benchmarks/bionic_benchmarks.cpp
+++ b/benchmarks/bionic_benchmarks.cpp
@@ -306,21 +306,21 @@
std::map<std::string, args_vector_t> GetShorthand() {
std::map<std::string, args_vector_t> args_shorthand {
{"AT_ALIGNED_TWOBUF", args_vector_t{ {8, 0, 0},
- {64, 0, 0},
- {512, 0, 0},
- {1 * KB, 0, 0},
- {8 * KB, 0, 0},
- {16 * KB, 0, 0},
- {32 * KB, 0, 0},
- {64 * KB, 0, 0} }},
+ {64, 0, 0},
+ {512, 0, 0},
+ {1 * KB, 0, 0},
+ {8 * KB, 0, 0},
+ {16 * KB, 0, 0},
+ {32 * KB, 0, 0},
+ {64 * KB, 0, 0} }},
{"AT_ALIGNED_ONEBUF", args_vector_t{ {(8), 0},
- {(64), 0},
- {(512), 0},
- {(1*KB), 0},
- {(8*KB), 0},
- {(16*KB), 0},
- {(32*KB), 0},
- {(64*KB), 0}}},
+ {(64), 0},
+ {(512), 0},
+ {(1*KB), 0},
+ {(8*KB), 0},
+ {(16*KB), 0},
+ {(32*KB), 0},
+ {(64*KB), 0}}},
{"AT_COMMON_SIZES", args_vector_t{ {8}, {64}, {512}, {1*KB}, {8*KB}, {16*KB},
{32*KB}, {64*KB}}},
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 756a698..a1ca60e 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -63,9 +63,10 @@
BIONIC_BENCHMARK(BM_stdio_fwrite_unbuffered);
static void FopenFgetsFclose(benchmark::State& state, bool no_locking) {
- char buf[1024];
+ size_t nbytes = state.range(0);
+ char buf[nbytes];
while (state.KeepRunning()) {
- FILE* fp = fopen("/proc/version", "re");
+ FILE* fp = fopen("/dev/zero", "re");
if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
if (fgets(buf, sizeof(buf), fp) == nullptr) abort();
fclose(fp);
@@ -81,3 +82,27 @@
FopenFgetsFclose(state, true);
}
BIONIC_BENCHMARK(BM_stdio_fopen_fgets_fclose_no_locking);
+
+static void FopenFgetcFclose(benchmark::State& state, bool no_locking) {
+ size_t nbytes = state.range(0);
+ while (state.KeepRunning()) {
+ FILE* fp = fopen("/dev/zero", "re");
+ if (no_locking) __fsetlocking(fp, FSETLOCKING_BYCALLER);
+ volatile int c __attribute__((unused));
+ for (size_t i = 0; i < nbytes; ++i) {
+ c = fgetc(fp);
+ }
+ fclose(fp);
+ }
+}
+
+static void BM_stdio_fopen_fgetc_fclose_locking(benchmark::State& state) {
+ FopenFgetcFclose(state, false);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetc_fclose_locking);
+
+void BM_stdio_fopen_fgetc_fclose_no_locking(benchmark::State& state) {
+ FopenFgetcFclose(state, true);
+}
+BIONIC_BENCHMARK(BM_stdio_fopen_fgetc_fclose_no_locking);
+
diff --git a/benchmarks/stdlib_benchmark.cpp b/benchmarks/stdlib_benchmark.cpp
new file mode 100644
index 0000000..7a12eb6
--- /dev/null
+++ b/benchmarks/stdlib_benchmark.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <langinfo.h>
+#include <locale.h>
+#include <stdlib.h>
+
+#include <benchmark/benchmark.h>
+#include "util.h"
+
+static void BM_stdlib_malloc_free(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+
+ void* c;
+ while (state.KeepRunning()) {
+ c = malloc(nbytes);
+ free(c);
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BIONIC_BENCHMARK(BM_stdlib_malloc_free);
+
+static void BM_stdlib_mbstowcs(benchmark::State& state) {
+ const size_t buf_alignment = state.range(0);
+ const size_t widebuf_alignment = state.range(1);
+
+ std::vector<char> buf;
+ std::vector<wchar_t> widebuf;
+
+ setlocale(LC_CTYPE, "C.UTF-8")
+ || setlocale(LC_CTYPE, "en_US.UTF-8")
+ || setlocale(LC_CTYPE, "en_GB.UTF-8")
+ || setlocale(LC_CTYPE, "en.UTF-8")
+ || setlocale(LC_CTYPE, "de_DE-8")
+ || setlocale(LC_CTYPE, "fr_FR-8");
+ if (strcmp(nl_langinfo(CODESET), "UTF-8")) abort();
+
+ char* buf_aligned = GetAlignedPtr(&buf, buf_alignment, 500000);
+ wchar_t* widebuf_aligned = GetAlignedPtr(&widebuf, widebuf_alignment, 500000);
+ size_t i, j, k, l;
+ l = 0;
+ for (i=0xc3; i<0xe0; i++)
+ for (j=0x80; j<0xc0; j++)
+ buf[l++] = i, buf[l++] = j;
+ for (i=0xe1; i<0xed; i++)
+ for (j=0x80; j<0xc0; j++)
+ for (k=0x80; k<0xc0; k++)
+ buf[l++] = i, buf[l++] = j, buf[l++] = k;
+ for (i=0xf1; i<0xf4; i++)
+ for (j=0x80; j<0xc0; j++)
+ for (k=0x80; k<0xc0; k++)
+ buf[l++] = i, buf[l++] = j, buf[l++] = 0x80, buf[l++] = k;
+ buf[l++] = 0;
+
+ volatile size_t c __attribute__((unused)) = 0;
+ while (state.KeepRunning()) {
+ c = mbstowcs(widebuf_aligned, buf_aligned, 500000);
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(500000));
+}
+BIONIC_BENCHMARK(BM_stdlib_mbstowcs);
+
+static void BM_stdlib_mbrtowc(benchmark::State& state) {
+ const size_t buf_alignment = state.range(0);
+
+ std::vector<char> buf;
+
+ setlocale(LC_CTYPE, "C.UTF-8")
+ || setlocale(LC_CTYPE, "en_US.UTF-8")
+ || setlocale(LC_CTYPE, "en_GB.UTF-8")
+ || setlocale(LC_CTYPE, "en.UTF-8")
+ || setlocale(LC_CTYPE, "de_DE-8")
+ || setlocale(LC_CTYPE, "fr_FR-8");
+ if (strcmp(nl_langinfo(CODESET), "UTF-8")) abort();
+
+ char* buf_aligned = GetAlignedPtr(&buf, buf_alignment, 500000);
+ size_t i, j, k, l;
+ l = 0;
+ for (i=0xc3; i<0xe0; i++)
+ for (j=0x80; j<0xc0; j++)
+ buf[l++] = i, buf[l++] = j;
+ for (i=0xe1; i<0xed; i++)
+ for (j=0x80; j<0xc0; j++)
+ for (k=0x80; k<0xc0; k++)
+ buf[l++] = i, buf[l++] = j, buf[l++] = k;
+ for (i=0xf1; i<0xf4; i++)
+ for (j=0x80; j<0xc0; j++)
+ for (k=0x80; k<0xc0; k++)
+ buf[l++] = i, buf[l++] = j, buf[l++] = 0x80, buf[l++] = k;
+ buf[l++] = 0;
+
+ wchar_t wc = 0;
+ while (state.KeepRunning()) {
+ for (j = 0; buf_aligned[j]; j+=mbrtowc(&wc, buf_aligned + j, 4, NULL)) {
+ }
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(500000));
+}
+BIONIC_BENCHMARK(BM_stdlib_mbrtowc);
diff --git a/benchmarks/string_benchmark.cpp b/benchmarks/string_benchmark.cpp
index 729b20d..94e7583 100644
--- a/benchmarks/string_benchmark.cpp
+++ b/benchmarks/string_benchmark.cpp
@@ -241,3 +241,49 @@
state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
}
BIONIC_BENCHMARK(BM_string_strcmp);
+
+static void BM_string_strstr(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ const size_t haystack_alignment = state.range(1);
+ const size_t needle_alignment = state.range(2);
+
+ std::vector<char> haystack;
+ std::vector<char> needle;
+ char* haystack_aligned = GetAlignedPtrFilled(&haystack, haystack_alignment, nbytes, 'x');
+ char* needle_aligned = GetAlignedPtrFilled(&needle, needle_alignment,
+ std::min(nbytes, static_cast<size_t>(5)), 'x');
+
+ if (nbytes / 4 > 2) {
+ for (size_t i = 0; nbytes / 4 >= 2 && i < nbytes / 4 - 2; i++) {
+ haystack_aligned[4 * i + 3] = 'y';
+ }
+ }
+ haystack_aligned[nbytes - 1] = '\0';
+ needle_aligned[needle.size() - 1] = '\0';
+
+ while (state.KeepRunning()) {
+ if (strstr(haystack_aligned, needle_aligned) == nullptr) {
+ abort();
+ }
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BIONIC_BENCHMARK(BM_string_strstr);
+
+static void BM_string_strchr(benchmark::State& state) {
+ const size_t nbytes = state.range(0);
+ const size_t haystack_alignment = state.range(1);
+
+ std::vector<char> haystack;
+ char* haystack_aligned = GetAlignedPtrFilled(&haystack, haystack_alignment, nbytes, 'x');
+
+ while (state.KeepRunning()) {
+ if (strchr(haystack_aligned, 'y') != nullptr) {
+ abort();
+ }
+ }
+
+ state.SetBytesProcessed(uint64_t(state.iterations()) * uint64_t(nbytes));
+}
+BIONIC_BENCHMARK(BM_string_strchr);
diff --git a/benchmarks/suites/full.xml b/benchmarks/suites/full.xml
index 707a3d6..8c9aef6 100644
--- a/benchmarks/suites/full.xml
+++ b/benchmarks/suites/full.xml
@@ -180,9 +180,19 @@
</fn>
<fn>
<name>BM_stdio_fopen_fgets_fclose_locking</name>
+ <args>1024</args>
</fn>
<fn>
<name>BM_stdio_fopen_fgets_fclose_no_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_no_locking</name>
+ <args>1024</args>
</fn>
<fn>
<name>BM_string_memcmp</name>
@@ -233,6 +243,14 @@
<args>AT_ALIGNED_TWOBUF</args>
</fn>
<fn>
+ <name>BM_string_strstr</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strchr</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
<name>BM_time_clock_gettime</name>
</fn>
<fn>
@@ -265,3 +283,15 @@
<fn>
<name>BM_unistd_gettid_syscall</name>
</fn>
+<fn>
+ <name>BM_stdlib_malloc_free</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbstowcs</name>
+ <args>0 0</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbrtowc</name>
+ <args>0</args>
+</fn>
diff --git a/benchmarks/suites/host.xml b/benchmarks/suites/host.xml
index c4d0d3a..05769e9 100644
--- a/benchmarks/suites/host.xml
+++ b/benchmarks/suites/host.xml
@@ -160,9 +160,19 @@
</fn>
<fn>
<name>BM_stdio_fopen_fgets_fclose_locking</name>
+ <args>1024</args>
</fn>
<fn>
<name>BM_stdio_fopen_fgets_fclose_no_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_no_locking</name>
+ <args>1024</args>
</fn>
<fn>
<name>BM_string_memcmp</name>
@@ -213,6 +223,14 @@
<args>AT_ALIGNED_TWOBUF</args>
</fn>
<fn>
+ <name>BM_string_strstr</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strchr</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
<name>BM_time_clock_gettime</name>
</fn>
<fn>
@@ -242,3 +260,15 @@
<fn>
<name>BM_unistd_gettid_syscall</name>
</fn>
+<fn>
+ <name>BM_stdlib_malloc_free</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbstowcs</name>
+ <args>0 0</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbrtowc</name>
+ <args>0</args>
+</fn>
diff --git a/benchmarks/suites/test_full.xml b/benchmarks/suites/test_full.xml
index f9d97ee..adc3f28 100644
--- a/benchmarks/suites/test_full.xml
+++ b/benchmarks/suites/test_full.xml
@@ -180,9 +180,19 @@
</fn>
<fn>
<name>BM_stdio_fopen_fgets_fclose_locking</name>
+ <args>1024</args>
</fn>
<fn>
<name>BM_stdio_fopen_fgets_fclose_no_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_locking</name>
+ <args>1024</args>
+</fn>
+<fn>
+ <name>BM_stdio_fopen_fgetc_fclose_no_locking</name>
+ <args>1024</args>
</fn>
<fn>
<name>BM_string_memcmp</name>
@@ -233,6 +243,14 @@
<args>AT_ALIGNED_TWOBUF</args>
</fn>
<fn>
+ <name>BM_string_strstr</name>
+ <args>AT_ALIGNED_TWOBUF</args>
+</fn>
+<fn>
+ <name>BM_string_strchr</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
<name>BM_time_clock_gettime</name>
</fn>
<fn>
@@ -259,3 +277,15 @@
<fn>
<name>BM_unistd_gettid_syscall</name>
</fn>
+<fn>
+ <name>BM_stdlib_malloc_free</name>
+ <args>AT_ALIGNED_ONEBUF</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbstowcs</name>
+ <args>0 0</args>
+</fn>
+<fn>
+ <name>BM_stdlib_mbrtowc</name>
+ <args>0</args>
+</fn>
diff --git a/benchmarks/tests/interface_test.cpp b/benchmarks/tests/interface_test.cpp
index a9e3031..9283e6b 100644
--- a/benchmarks/tests/interface_test.cpp
+++ b/benchmarks/tests/interface_test.cpp
@@ -242,8 +242,10 @@
"BM_stdio_fwrite_unbuffered/16384/iterations:1\n"
"BM_stdio_fwrite_unbuffered/32768/iterations:1\n"
"BM_stdio_fwrite_unbuffered/65536/iterations:1\n"
- "BM_stdio_fopen_fgets_fclose_locking/iterations:1\n"
- "BM_stdio_fopen_fgets_fclose_no_locking/iterations:1\n"
+ "BM_stdio_fopen_fgets_fclose_locking/1024/iterations:1\n"
+ "BM_stdio_fopen_fgets_fclose_no_locking/1024/iterations:1\n"
+ "BM_stdio_fopen_fgetc_fclose_locking/1024/iterations:1\n"
+ "BM_stdio_fopen_fgetc_fclose_no_locking/1024/iterations:1\n"
"BM_string_memcmp/8/0/0/iterations:1\n"
"BM_string_memcmp/64/0/0/iterations:1\n"
"BM_string_memcmp/512/0/0/iterations:1\n"
@@ -340,6 +342,22 @@
"BM_string_strcmp/16384/0/0/iterations:1\n"
"BM_string_strcmp/32768/0/0/iterations:1\n"
"BM_string_strcmp/65536/0/0/iterations:1\n"
+ "BM_string_strstr/8/0/0/iterations:1\n"
+ "BM_string_strstr/64/0/0/iterations:1\n"
+ "BM_string_strstr/512/0/0/iterations:1\n"
+ "BM_string_strstr/1024/0/0/iterations:1\n"
+ "BM_string_strstr/8192/0/0/iterations:1\n"
+ "BM_string_strstr/16384/0/0/iterations:1\n"
+ "BM_string_strstr/32768/0/0/iterations:1\n"
+ "BM_string_strstr/65536/0/0/iterations:1\n"
+ "BM_string_strchr/8/0/iterations:1\n"
+ "BM_string_strchr/64/0/iterations:1\n"
+ "BM_string_strchr/512/0/iterations:1\n"
+ "BM_string_strchr/1024/0/iterations:1\n"
+ "BM_string_strchr/8192/0/iterations:1\n"
+ "BM_string_strchr/16384/0/iterations:1\n"
+ "BM_string_strchr/32768/0/iterations:1\n"
+ "BM_string_strchr/65536/0/iterations:1\n"
"BM_time_clock_gettime/iterations:1\n"
"BM_time_clock_gettime_syscall/iterations:1\n"
"BM_time_gettimeofday/iterations:1\n"
@@ -348,7 +366,17 @@
"BM_unistd_getpid/iterations:1\n"
"BM_unistd_getpid_syscall/iterations:1\n"
"BM_unistd_gettid/iterations:1\n"
- "BM_unistd_gettid_syscall/iterations:1\n";
+ "BM_unistd_gettid_syscall/iterations:1\n"
+ "BM_stdlib_malloc_free/8/0/iterations:1\n"
+ "BM_stdlib_malloc_free/64/0/iterations:1\n"
+ "BM_stdlib_malloc_free/512/0/iterations:1\n"
+ "BM_stdlib_malloc_free/1024/0/iterations:1\n"
+ "BM_stdlib_malloc_free/8192/0/iterations:1\n"
+ "BM_stdlib_malloc_free/16384/0/iterations:1\n"
+ "BM_stdlib_malloc_free/32768/0/iterations:1\n"
+ "BM_stdlib_malloc_free/65536/0/iterations:1\n"
+ "BM_stdlib_mbstowcs/0/0/iterations:1\n"
+ "BM_stdlib_mbrtowc/0/iterations:1\n";
Verify(expected, 0, std::vector<const char *>{"--bionic_xml=suites/test_full.xml",
"--bionic_iterations=1"});
}
diff --git a/benchmarks/util.cpp b/benchmarks/util.cpp
index 9afca6f..0c7254c 100644
--- a/benchmarks/util.cpp
+++ b/benchmarks/util.cpp
@@ -16,9 +16,11 @@
#include "util.h"
+#include <math.h>
#include <sched.h>
#include <stdio.h>
#include <string.h>
+#include <wchar.h>
#include <cstdlib>
@@ -49,6 +51,12 @@
return GetAlignedMemory(buf->data(), alignment, 0);
}
+wchar_t* GetAlignedPtr(std::vector<wchar_t>* buf, size_t alignment, size_t nchars) {
+ buf->resize(nchars + ceil((3 * alignment) / sizeof(wchar_t)));
+ return reinterpret_cast<wchar_t*>(GetAlignedMemory(reinterpret_cast<char*>(buf->data()),
+ alignment, 0));
+}
+
char* GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte) {
char* buf_aligned = GetAlignedPtr(buf, alignment, nbytes);
memset(buf_aligned, fill_byte, nbytes);
diff --git a/benchmarks/util.h b/benchmarks/util.h
index c8c39e3..cf6f50e 100644
--- a/benchmarks/util.h
+++ b/benchmarks/util.h
@@ -52,6 +52,8 @@
char* GetAlignedPtr(std::vector<char>* buf, size_t alignment, size_t nbytes);
+wchar_t* GetAlignedPtr(std::vector<wchar_t>* buf, size_t alignment, size_t nbytes);
+
char* GetAlignedPtrFilled(std::vector<char>* buf, size_t alignment, size_t nbytes, char fill_byte);
bool LockToCPU(long cpu_to_lock);