From d820e8ff8a924b4fca3f19b42bb937b01bdb6b61 Mon Sep 17 00:00:00 2001 From: Mukund Sivaraman Date: Fri, 4 Mar 2016 13:41:54 +0530 Subject: [PATCH] Add dns_name_fromwire() benchmark (cherry picked from commit 59328c76745ee6d2df047e3f072b118258b87cb6) --- CHANGES | 2 + lib/dns/tests/name_test.c | 107 ++++++++++++++++++++++++++++++++++++++ lib/dns/tests/rbt_test.c | 8 +-- 3 files changed, 113 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index f4a8d60d21..27982a10b5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +4328. [performance] Add dns_name_fromwire() benchmark test. [RT #41694] + 4327. [func] Log query and depth counters during fetches when querytrace is enabled (helps in diagnosing). [RT #41787] diff --git a/lib/dns/tests/name_test.c b/lib/dns/tests/name_test.c index b5f9f9c7ff..efed92073b 100644 --- a/lib/dns/tests/name_test.c +++ b/lib/dns/tests/name_test.c @@ -24,6 +24,8 @@ #include +#include + #include #include #include "dnstest.h" @@ -117,11 +119,116 @@ ATF_TC_BODY(fullcompare, tc) { } } +#ifdef DNS_BENCHMARK_TESTS + +/* + * XXXMUKS: Don't delete this code. It is useful in benchmarking the + * name parser, but we don't require it as part of the unit test runs. + */ + +ATF_TC(benchmark); +ATF_TC_HEAD(benchmark, tc) { + atf_tc_set_md_var(tc, "descr", + "Benchmark dns_name_fromwire() implementation"); +} + +static void * +fromwire_thread(void *arg) { + unsigned int maxval = 32000000; + uint8_t data[] = { + 3, 'w', 'w', 'w', + 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', + 7, 'i', 'n', 'v', 'a', 'l', 'i', 'd', + 0 + }; + unsigned char output_data[DNS_NAME_MAXWIRE]; + isc_buffer_t source, target; + unsigned int i; + dns_decompress_t dctx; + + UNUSED(arg); + + dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT); + dns_decompress_setmethods(&dctx, DNS_COMPRESS_NONE); + + isc_buffer_init(&source, data, sizeof(data)); + isc_buffer_add(&source, sizeof(data)); + isc_buffer_init(&target, output_data, sizeof(output_data)); + + /* Parse 32 million names in each thread */ + for (i = 0; i < maxval; i++) { + dns_name_t name; + + isc_buffer_clear(&source); + isc_buffer_clear(&target); + isc_buffer_add(&source, sizeof(data)); + isc_buffer_setactive(&source, sizeof(data)); + + dns_name_init(&name, NULL); + (void) dns_name_fromwire(&name, &source, &dctx, 0, &target); + } + + return (NULL); +} + +ATF_TC_BODY(benchmark, tc) { + isc_result_t result; + unsigned int i; + isc_time_t ts1, ts2; + double t; + unsigned int nthreads; + pthread_t threads[32]; + + UNUSED(tc); + + debug_mem_record = ISC_FALSE; + + result = dns_test_begin(NULL, ISC_TRUE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = isc_time_now(&ts1); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + nthreads = ISC_MIN(isc_os_ncpus(), 32); + nthreads = ISC_MAX(nthreads, 1); + for (i = 0; i < nthreads; i++) { + int s; + + s = pthread_create(&threads[i], NULL, fromwire_thread, NULL); + + ATF_REQUIRE(s == 0); + } + + for (i = 0; i < nthreads; i++) { + int s; + + s = pthread_join(threads[i], NULL); + + ATF_REQUIRE(s == 0); + } + + result = isc_time_now(&ts2); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + t = isc_time_microdiff(&ts2, &ts1); + + printf("%u dns_name_fromwire() calls, %f seconds, %f calls/second\n", + nthreads * 32000000, t / 1000000.0, + (nthreads * 32000000) / (t / 1000000.0)); + + dns_test_end(); +} + +#endif /* DNS_BENCHMARK_TESTS */ + /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, fullcompare); +#ifdef DNS_BENCHMARK_TESTS + ATF_TP_ADD_TC(tp, benchmark); +#endif /* DNS_BENCHMARK_TESTS */ return (atf_no_error()); } diff --git a/lib/dns/tests/rbt_test.c b/lib/dns/tests/rbt_test.c index b8cf8cfb76..4d0ca09757 100644 --- a/lib/dns/tests/rbt_test.c +++ b/lib/dns/tests/rbt_test.c @@ -1308,7 +1308,7 @@ ATF_TC_BODY(rbt_insert_and_remove, tc) { dns_test_end(); } -#if 0 +#ifdef DNS_BENCHMARK_TESTS /* * XXXMUKS: Don't delete this code. It is useful in benchmarking the @@ -1440,7 +1440,7 @@ ATF_TC_BODY(benchmark, tc) { dns_test_end(); } -#endif /* benchmark test */ +#endif /* DNS_BENCHMARK_TESTS */ /* * Main @@ -1455,9 +1455,9 @@ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, rbt_remove); ATF_TP_ADD_TC(tp, rbt_remove_empty); ATF_TP_ADD_TC(tp, rbt_insert_and_remove); -#if 0 +#ifdef DNS_BENCHMARK_TESTS ATF_TP_ADD_TC(tp, benchmark); -#endif +#endif /* DNS_BENCHMARK_TESTS */ return (atf_no_error()); }