ndfred / iperf-ios

iPerf 3 library and app for iOS
Other
188 stars 26 forks source link

Make tests more efficient to run #8

Open ndfred opened 5 years ago

ndfred commented 5 years ago

There are a few tricks on the iperf3 at 40Gbps and above page that could apply to tests on mobile devices too:

ndfred commented 5 years ago

Running Instruments (on a simulator) we see most time spent in:

12.5% in result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout); in iperf_run_client 67.9% in r = write(fd, buf, nleft); in Nwrite

Instruments
ndfred commented 5 years ago

iperf_new_stream will create a temporary file but immediately delete it and mmaps that region to a buffer of 130kb. The test still runs if MAP_ANONYMOUS is passed to mmap and the file descriptor is -1, which makes me think we can patch the source and avoid creating a file altogether.

ndfred commented 5 years ago

The library uses JSON and might output quite a bit of text when running a test, maybe worth avoiding, though profiling suggests otherwise, and that code is needed to properly function as a server eventually

ndfred commented 5 years ago

Analysing the data used for profile guided optimisations with llvm-profdata show -topn=50 iperf.profdata, these are the top called methods, we see quite a bit of JSON activity which we could get rid of:

Top 50 functions with the largest internal block counts: iperf_recv, max count = 479940 iperf_api.c:darwin_fd_isset, max count = 479940 Nread, max count = 355048 timer.c:getnow, max count = 193583 iperf_tcp_recv, max count = 100847 tmr_timeout, max count = 97594 iperf_run_client, max count = 97594 iperf_client_api.c:darwin_fd_isset, max count = 97579 tmr_run, max count = 96047 cjson.c:print_string_ptr, max count = 404 cjson.c:case_insensitive_strcmp, max count = 327 cjson.c:parse_string, max count = 291 cjson.c:ensure, max count = 231 cjson.c:print_number, max count = 223 cjson.c:get_object_item, max count = 185 timeval_diff, max count = 160 cjson.c:buffer_skip_whitespace, max count = 158 iperf_stats_callback, max count = 150 iperf_free_stream, max count = 150 add_to_interval_list, max count = 150 has_tcpinfo, max count = 150 IPFTestRunner.m:-[IPFTestRunner handleStatsCallback:], max count = 150 cjson.c:parse_number, max count = 139 cJSON_AddItemToArray, max count = 138 cjson.c:update_offset, max count = 113 cjson.c:cJSON_New_Item, max count = 101 cJSON_Delete, max count = 101 cjson.c:get_decimal_point, max count = 83 timer.c:list_add, max count = 63 timer.c:list_remove, max count = 63 timer.c:add_usecs, max count = 63 cjson.c:print_value, max count = 60 timer.c:list_resort, max count = 60 cjson.c:cJSON_strdup, max count = 54 cJSON_AddItemToObject, max count = 53 cJSON_AddItemToObjectCS, max count = 53 cjson.c:print_object, max count = 53 cjson.c:suffix_object, max count = 50 cJSON_CreateNumber, max count = 49 cJSON_GetObjectItem, max count = 46 cjson.c:parse_value, max count = 41 make_cookie, max count = 36 cjson.c:parse_object, max count = 35 IPFTestRunner.m:dispatch_get_main_queue, max count = 31 IPFTestRunnerViewController.m:40-[IPFTestRunnerViewController startTest]_block_invoke.126, max count = 31 IPFTestRunner.m:vc_reporter_callback, max count = 30 iperf_client_api.c:client_stats_timer_proc, max count = 30 IPFTestRunner.m:vc_reporter_callback_block_invoke, max count = 30 iperf_client_api.c:client_reporter_timer_proc, max count = 30 iperf_api.c:get_results, max count = 15

ndfred commented 5 years ago

Actually the iPerf protocol uses JSON which is why we are seeing so much of it, not a big deal