diff --git a/.clang-format b/.clang-format index 6d333bf..10aa9f0 100644 --- a/.clang-format +++ b/.clang-format @@ -4,7 +4,7 @@ BasedOnStyle: LLVM IndentWidth: 4 ColumnLimit: 100 AllowShortBlocksOnASingleLine: Empty -# AllowShortFunctionsOnASingleLine: Inline +AllowShortFunctionsOnASingleLine: Inline AllowShortLoopsOnASingleLine: true AllowShortIfStatementsOnASingleLine: Never AlignConsecutiveMacros: true diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f29800..b8b08c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,11 +8,6 @@ endif() set(CMAKE_C_STANDARD 23) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O3 -Wall -Wextra -Wno-unused-parameter") -if (DPDK) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") -elseif (SCHED_POLICY MATCHES "^(fifo|rr|cfs)$") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mno-sse") -endif() set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wextra -Wall") @@ -52,6 +47,10 @@ if(UINTR) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -muintr") endif() +if(FXSAVE) + add_definitions(-DSKYLOFT_FXSAVE) +endif() + if(LOG_LEVEL) if(NOT LOG_LEVEL MATCHES "^(debug|info|notice|warn|err|crit)$") message(FATAL_ERROR "Invalid log level: ${LOG_LEVEL}") @@ -60,7 +59,6 @@ if(LOG_LEVEL) string(TOUPPER ${LOG_LEVEL} LOG_LEVEL_UPPER) add_definitions(-DLOG_LEVEL_${LOG_LEVEL_UPPER}) endif() - message(STATUS "Log level: ${LOG_LEVEL}") if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") @@ -91,3 +89,9 @@ else() add_subdirectory(apps) endif() +add_custom_target( + microbench + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/microbench + COMMAND make clean && make SKYLOFT_DIR=${CMAKE_CURRENT_BINARY_DIR}/install + COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/microbench/thread ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/thread +) diff --git a/Makefile b/Makefile index 66e9465..9ade575 100644 --- a/Makefile +++ b/Makefile @@ -5,15 +5,25 @@ UINTR ?= 0 SCHED ?= fifo DAEMON ?= DEBUG ?= -STAT ?= +STAT ?= 0 LOG ?= info +FXSAVE ?= 0 CC ?= gcc CFLAGS := -Wall -O2 -D_GNU_SOURCE CMAKE_ARGS ?= CMAKE_ARGS += -DSCHED_POLICY=$(SCHED) -CMAKE_ARGS += -DSIGNAL=$(SIGNAL) -DDPDK=$(DPDK) -DTIMER=$(TIMER) -DUINTR=$(UINTR) -DDAEMON=$(DAEMON) -DDEBUG=$(DEBUG) -DSTAT=$(STAT) -DLOG_LEVEL=$(LOG) +CMAKE_ARGS += \ + -DSIGNAL=$(SIGNAL) \ + -DDPDK=$(DPDK) \ + -DTIMER=$(TIMER) \ + -DUINTR=$(UINTR) \ + -DDAEMON=$(DAEMON) \ + -DDEBUG=$(DEBUG) \ + -DSTAT=$(STAT) \ + -DLOG_LEVEL=$(LOG) \ + -DFXSAVE=$(FXSAVE) CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=install all: build @@ -46,8 +56,11 @@ schbench: install rocksdb: install cd build && make rocksdb_server VERBOSE=1 +microbench: install + cd build && make microbench VERBOSE=1 + fmt: - @clang-format --style=file -i $(shell find utils/ libos/ apps/ tests/ experiments/ -iname '*.c' -o -iname '*.cc' -o -iname '*.h') + @clang-format --style=file -i $(shell find utils/ libos/ apps/ synthetic/ -iname '*.c' -o -iname '*.cc' -o -iname '*.h') clean: make -C build clean diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index e9b38a2..090aed0 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -21,19 +21,14 @@ target_link_libraries(test_timer skyloft utils) add_executable(test_rcu test_rcu.c) target_link_libraries(test_rcu skyloft utils) -add_executable(test_net test_net.c) -target_link_libraries(test_net skyloft utils) - if(DPDK) - add_executable(fakework fakework.c) - target_link_libraries(fakework skyloft utils) - include(${CMAKE_SCRIPTS}/rocksdb.mk) add_custom_target( rocksdb_server WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb_server COMMAND make clean && make SKYLOFT_DIR=${CMAKE_CURRENT_BINARY_DIR}/../install ROCKSDB_SRC=${rocksdb_SOURCE_DIR}/ COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb_server/rocksdb_server ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/rocksdb_server + COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb_server/create_db ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/create_db ) add_dependencies(rocksdb_server librocksdb) endif() diff --git a/apps/fakework.c b/apps/fakework.c deleted file mode 100644 index 2c01656..0000000 --- a/apps/fakework.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include - -static struct netaddr listen_addr; - -static void __attribute__((noinline)) fake_work(unsigned int nloops) -{ - for (unsigned int i = 0; i++ < nloops;) { - asm volatile("nop"); - } -} - -// Shenango loadgen message format -struct payload { - uint64_t work_iterations; - uint64_t index; -}; - -extern __thread struct task* __curr; - -static void HandleRequest(udp_spawn_data_t *d) -{ - unsigned int niters = 0; - - if (d->len == sizeof(struct payload)) { - struct payload *p = (struct payload *)d->buf; - niters = ntoh64(p->work_iterations) * CPU_FREQ_MHZ / 1000; - } else { - panic("invalid message len %lu", d->len); - } - - // printf("niters: %d\n", niters); - // uint64_t a = now_tsc(); - - __curr->allow_preempt = true; - fake_work(niters); - __curr->allow_preempt = false; - // uint64_t b = now_tsc(); - // printf(" %ld\n", b - a); - - if (udp_respond(d->buf, d->len, d) != (ssize_t)d->len) - panic("bad write"); - udp_spawn_data_release(d->release_data); -} - -static void app_main(void *arg) -{ - udp_spawner_t *s; - waitgroup_t w; - - int ret = udp_create_spawner(listen_addr, HandleRequest, &s); - if (ret) - panic("ret %d", ret); - - waitgroup_init(&w); - waitgroup_add(&w, 1); - waitgroup_wait(&w); -} - -int main(int argc, char *argv[]) -{ - int ret; - - if (argc != 2) { - printf("usage: %s [portno]\n", argv[0]); - return -EINVAL; - } - - listen_addr.port = atoi(argv[1]); - - ret = sl_libos_start(app_main, NULL); - if (ret) { - printf("failed to start runtime\n"); - return ret; - } - - return 0; -} diff --git a/apps/rocksdb_server/.gitignore b/apps/rocksdb_server/.gitignore new file mode 100644 index 0000000..a8af0c9 --- /dev/null +++ b/apps/rocksdb_server/.gitignore @@ -0,0 +1,2 @@ +rocksdb_server +create_db diff --git a/apps/rocksdb_server/Makefile b/apps/rocksdb_server/Makefile new file mode 100644 index 0000000..fa19cd2 --- /dev/null +++ b/apps/rocksdb_server/Makefile @@ -0,0 +1,53 @@ +SKYLOFT_DIR ?= +ROCKSDB_SRC ?= + +CFLAGS = -I$(SKYLOFT_DIR)/include -DSKYLOFT +SKYLOFT_LIBS = $(SKYLOFT_DIR)/lib/libskyloft.a $(SKYLOFT_DIR)/lib/libutils.a +SKYLOFT_LDFLAGS = -T $(SKYLOFT_DIR)/lib/libos.ld -lnuma +SKYLOFT_LDFLAGS += $(shell pkg-config --libs libdpdk) + +CFLAGS += -I$(ROCKSDB_SRC)/include/rocksdb/ +ROCKSDB_LIBS = $(ROCKSDB_SRC)/librocksdb.a +ROCKSDB_LDFLAGS = -lpthread -ldl -lz -lbz2 -lsnappy -lzstd -lstdc++ -lm + +ifneq ($(DEBUG),) +CFLAGS += -DDEBUG -rdynamic -O0 -ggdb +LDFLAGS += -rdynamic +else +CFLAGS += -DNDEBUG -O3 +endif + +CC = gcc +CXX = g++ +LD = gcc + +rocksdb_server_src = rocksdb_server.cc +rocksdb_server_obj = $(rocksdb_server_src:.cc=.o) + +create_db_src = create_db.cc +create_db_obj = $(create_db_src:.cc=.o) + +src = $(rocksdb_server_src) $(create_db_src) +obj = $(rocksdb_server_obj) $(create_db_obj) + +# must be first +all: rocksdb_server create_db + +$(ROCKSDB_LIBS): + make -j -C rocksdb static_lib + +rocksdb_server: $(rocksdb_server_obj) $(SKYLOFT_LIBS) $(ROCKSDB_LIBS) + $(LD) -o $@ $^ $(SKYLOFT_LDFLAGS) $(ROCKSDB_LDFLAGS) + +create_db: $(create_db_obj) $(ROCKSDB_LIBS) + $(LD) -o $@ $^ $(ROCKSDB_LDFLAGS) + +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +%.o: %.cc + $(CXX) $(CFLAGS) -c $< -o $@ + +.PHONY: clean +clean: + rm -f $(obj) rocksdb_server \ No newline at end of file diff --git a/apps/rocksdb_server/create_db.cc b/apps/rocksdb_server/create_db.cc new file mode 100644 index 0000000..60d8527 --- /dev/null +++ b/apps/rocksdb_server/create_db.cc @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +#include "c.h" + +#include // sysconf() - get CPU count + +const char DBPath[] = "/tmp/my_db"; + +int main(int argc, char **argv) +{ + rocksdb_t *db; + rocksdb_backup_engine_t *be; + rocksdb_options_t *options = rocksdb_options_create(); + + rocksdb_slicetransform_t *prefix_extractor = rocksdb_slicetransform_create_fixed_prefix(8); + rocksdb_options_set_prefix_extractor(options, prefix_extractor); + rocksdb_options_set_plain_table_factory(options, 0, 10, 0.75, 3); + + // Optimize RocksDB. This is the easiest way to + // get RocksDB to perform well + long cpus = sysconf(_SC_NPROCESSORS_ONLN); // get # of online cores + rocksdb_options_increase_parallelism(options, (int)(cpus)); + rocksdb_options_optimize_level_style_compaction(options, 512 * 1024 * 1024); + // create the DB if it's not already present + rocksdb_options_set_create_if_missing(options, 1); + + // open DB + char *err = NULL; + db = rocksdb_open(options, DBPath, &err); + if (err) { + printf("Failed to open DB: %s\n", err); + exit(1); + } + + // Setup RNG + std::random_device rd; + std::mt19937_64 e2(rd()); + std::uniform_int_distribution dist(std::llround(std::pow(2, 64))); + + // Put key-value + rocksdb_writeoptions_t *writeoptions = rocksdb_writeoptions_create(); + const char *value = "value"; + for (int i = 0; i < 5000; i++) { + char key[10]; + // char value[64]; + snprintf(key, sizeof(key), "key%d", i); + // snprintf(value, sizeof(value), "%lld", dist(e2)); + rocksdb_put(db, writeoptions, key, strlen(key), value, strlen(value) + 1, &err); + assert(!err); + } + + // Get value + rocksdb_readoptions_t *readoptions = rocksdb_readoptions_create(); + for (int i = 0; i < 10000; i++) { + size_t len; + char key[10]; + snprintf(key, sizeof(key), "key%d", i); + char *returned_value = rocksdb_get(db, readoptions, key, strlen(key), &len, &err); + if (err) { + printf("GET failed: %s\n", err); + break; + } + printf("key: %s, Returned value: %s\n", key, returned_value); + if (i < 5000) { + assert(strcmp(returned_value, "value") == 0); + free(returned_value); + } else { + assert(!returned_value); + } + } + + // cleanup + rocksdb_writeoptions_destroy(writeoptions); + // rocksdb_readoptions_destroy(readoptions); + rocksdb_options_destroy(options); + rocksdb_close(db); + + return 0; +} \ No newline at end of file diff --git a/apps/rocksdb_server/rocksdb_server.c b/apps/rocksdb_server/rocksdb_server.c new file mode 100644 index 0000000..2e42b05 --- /dev/null +++ b/apps/rocksdb_server/rocksdb_server.c @@ -0,0 +1,197 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static rocksdb_t *db; +static struct netaddr listen_addr; + +extern __thread struct task *__curr; + +// Shenango loadgen message format +struct payload { + uint64_t work_iterations; + uint64_t index; +}; + +static void __attribute__((noinline)) simulated_work(unsigned int nloops) +{ + for (unsigned int i = 0; i++ < nloops;) { + asm volatile("nop"); + } +} + +static inline void DoScan(rocksdb_readoptions_t *readoptions) +{ + const char *retr_key; + size_t klen; + + rocksdb_iterator_t *iter = rocksdb_create_iterator(db, readoptions); + rocksdb_iter_seek_to_first(iter); + while (rocksdb_iter_valid(iter)) { + retr_key = rocksdb_iter_key(iter, &klen); + printf("Scanned key %s\n", retr_key); + rocksdb_iter_next(iter); + } + rocksdb_iter_destroy(iter); +} + +static inline void DoGet(rocksdb_readoptions_t *readoptions) +{ + const char *retr_key; + size_t klen; + + rocksdb_iterator_t *iter = rocksdb_create_iterator(db, readoptions); + rocksdb_iter_seek_to_first(iter); + if (rocksdb_iter_valid(iter)) { + retr_key = rocksdb_iter_key(iter, &klen); + printf("Scanned key %s\n", retr_key); + } else { + printf("No keys found\n"); + } + rocksdb_iter_destroy(iter); +} + +static void HandleRequest(udp_spawn_data_t *d) +{ + rocksdb_readoptions_t *readoptions = rocksdb_readoptions_create(); + + struct payload *p = (struct payload *)d->buf; + uint64_t type = ntoh64(p->work_iterations) * CPU_FREQ_MHZ / 1000; + + __curr->allow_preempt = true; + simulated_work(type); + __curr->allow_preempt = false; + + rocksdb_readoptions_destroy(readoptions); + barrier(); + + if (udp_respond(d->buf, d->len, d) != (ssize_t)d->len) + panic("bad write"); + udp_spawn_data_release(d->release_data); +} + +static int cmpfunc(const void *a, const void *b) +{ + int arg1 = *(const int *)a; + int arg2 = *(const int *)b; + if (arg1 < arg2) + return -1; + if (arg1 > arg2) + return 1; + return 0; +} + +#define BENCH_ITER 5000 + +static void bench_ops() +{ + const int cycles_per_us = CPU_FREQ_MHZ; + uint64_t durations[BENCH_ITER]; + unsigned int i = 0; + uint64_t sum = 0; + + sum = 0; + for (i = 0; i < BENCH_ITER; i++) { + uint64_t start = now_tsc(); + rocksdb_readoptions_t *readoptions = rocksdb_readoptions_create(); + DoScan(readoptions); + rocksdb_readoptions_destroy(readoptions); + uint64_t end = now_tsc(); + durations[i] = end - start; + sum += durations[i]; + } + qsort(durations, BENCH_ITER, sizeof(uint64_t), cmpfunc); + + fprintf(stderr, "stats for %u SCANs: \n", i); + fprintf(stderr, "avg: %0.3f\n", (double)sum / (double)(cycles_per_us * BENCH_ITER)); + fprintf(stderr, "median: %0.3f\n", (double)durations[i / 2] / (double)cycles_per_us); + fprintf(stderr, "p99.9: %0.3f\n", (double)durations[i * 999 / 1000] / (double)cycles_per_us); + + sum = 0; + for (i = 0; i < BENCH_ITER; i++) { + uint64_t start = now_tsc(); + rocksdb_readoptions_t *readoptions = rocksdb_readoptions_create(); + DoGet(readoptions); + rocksdb_readoptions_destroy(readoptions); + uint64_t end = now_tsc(); + durations[i] = end - start; + sum += durations[i]; + } + + qsort(durations, BENCH_ITER, sizeof(uint64_t), cmpfunc); + fprintf(stderr, "stats for %u GETs: \n", i); + fprintf(stderr, "avg: %0.3f\n", (double)sum / (double)(cycles_per_us * BENCH_ITER)); + fprintf(stderr, "median: %0.3f\n", (double)durations[i / 2] / (double)cycles_per_us); + fprintf(stderr, "p99.9: %0.3f\n", (double)durations[i * 999 / 1000] / (double)cycles_per_us); +} + +void rocksdb_init(const char *path) +{ + log_info("Initialized RocksDB\n"); + + rocksdb_options_t *options = rocksdb_options_create(); + rocksdb_options_set_allow_mmap_reads(options, 1); + rocksdb_options_set_allow_mmap_writes(options, 1); + rocksdb_slicetransform_t *prefix_extractor = rocksdb_slicetransform_create_fixed_prefix(8); + rocksdb_options_set_prefix_extractor(options, prefix_extractor); + rocksdb_options_set_plain_table_factory(options, 0, 10, 0.75, 3); + // Optimize RocksDB. This is the easiest way to + // get RocksDB to perform well + rocksdb_options_increase_parallelism(options, 0); + rocksdb_options_optimize_level_style_compaction(options, 512 * 1024 * 1024); + // create the DB if it's not already present + rocksdb_options_set_create_if_missing(options, 0); + + char *err = NULL; + db = rocksdb_open(options, path, &err); + + if (err) { + printf("Could not open RocksDB database: %s\n", err); + return; + } +} + +static void app_main(void *arg) +{ + udp_spawner_t *s; + waitgroup_t w; + + // open DB + rocksdb_init("/tmp/my_db"); + // bench_ops(); + + int ret = udp_create_spawner(listen_addr, HandleRequest, &s); + if (ret) + panic("ret %d", ret); + + waitgroup_init(&w); + waitgroup_add(&w, 1); + waitgroup_wait(&w); +} + +int main(int argc, char *argv[]) +{ + int ret; + + if (argc != 2) { + printf("usage: %s [portno]\n", argv[0]); + return -EINVAL; + } + + listen_addr.port = atoi(argv[1]); + + ret = sl_libos_start(app_main, NULL); + if (ret) { + printf("failed to start runtime\n"); + return ret; + } + + return 0; +} diff --git a/apps/test_net.c b/apps/test_net.c deleted file mode 100644 index 01142d5..0000000 --- a/apps/test_net.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include - -static int str_to_ip(const char *str, uint32_t *addr) -{ - uint8_t a, b, c, d; - if (sscanf(str, "%hhu.%hhu.%hhu.%hhu", &a, &b, &c, &d) != 4) { - return -EINVAL; - } - - *addr = MAKE_IP_ADDR(a, b, c, d); - return 0; -} - -static int str_to_mac(const char *str, struct eth_addr *addr) -{ - size_t i; - static const char *fmts[] = {"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", - "%hhx%hhx%hhx%hhx%hhx%hhx"}; - - for (i = 0; i < ARRAY_SIZE(fmts); i++) { - if (sscanf(str, fmts[i], &addr->addr[0], &addr->addr[1], &addr->addr[2], &addr->addr[3], - &addr->addr[4], &addr->addr[5]) == 6) { - return 0; - } - } - return -EINVAL; -} - -static void entry(void *arg) -{ - uint32_t addr; - str_to_ip("192.168.1.3", &addr); - - for (;;) { - printf("Hello\n"); - timer_sleep(USEC_PER_SEC); - } -} - -int main() -{ - sl_libos_start(entry, NULL); -} diff --git a/apps/test_timer.c b/apps/test_timer.c index 00968a0..6900c85 100644 --- a/apps/test_timer.c +++ b/apps/test_timer.c @@ -4,9 +4,9 @@ #include -#include #include #include +#include #include #include #include diff --git a/docs/sosp24-ae.md b/docs/sosp24-ae.md index e819df4..1c12958 100644 --- a/docs/sosp24-ae.md +++ b/docs/sosp24-ae.md @@ -4,6 +4,24 @@ ### 1.1 Artifact Directory Layout +- `apps/`: Benchmark real-world applications +- `docs/`: Documents and images +- `synthetic/`: Benchmark c-FCFS and PS scheduling policies + - `rocksdb/`: Latency-critical application + - `antagonist/`: Batch application +- `kmod/`: Skyloft kernel module +- `libos/`: Skyloft main code + - `io/`: IO thread + - `net/`: Network stack + - `shim/`: Shim layer for POSIX APIs + - `sync/`: Synchronization primitives + - `mm/`: Memory management + - `sched/`: Schedulers +- `utils/`: Useful tools +- `scripts/`: Setup machine; run experiments +- `microbench/`: Microbenchmarks and prototypes + + ### 1.2 Main Experiments | Experiments | Figure/Table | Runtime | Description | @@ -12,7 +30,9 @@ | synthetic-single | Figure 6(a) | | Tail latency for a single synthetic latency-critical (LC) workload | | synthetic-multiple | Figure 6(b) & Figure 6(c) | | Tail latency and CPU share for co-located synthetic LC and best-effort (BE) workload | | memcached | Figure 7(a) | | Tail latency for a Memcached server | +| rocksdb | Figure 7(b) | | Tail latency for a rocksdb server | | preempt | Table 5 | | Preemption mechanism overhead | +| thread | Table 6 | | Threading overhead | ## 2. System Requirements @@ -67,6 +87,8 @@ Other software dependencies are provided in our GitHub repositories, and install ## 3. Getting Started +*You can skip 3.0 - 3.4 if you are using the environment provided by us.* + **Following instructions are for the Server.** ### 3.0 Check Requirements @@ -94,6 +116,8 @@ $ ./build.sh ### 3.3 Configure Kernel Commandline Parameters +We will mention it again if the command line needs to change through experiments. + Take GRUB as example: 1. Open `/etc/default/grub`, add or modify the line: @@ -120,7 +144,20 @@ Take GRUB as example: 6.0.0-skyloft-nohzfull+ ``` -### 3.4 Download Skyloft +### 3.4 Install DPDK + +Install DPDK v22.11 on the machine: + +```sh +$ git clone https://github.com/yhtzd/dpdk.git +$ cd dpdk +$ meson build +$ cd build +$ ninja +$ sudo meson install +``` + +### 3.5 Download Skyloft ```sh $ git clone https://github.com/yhtzd/skyloft.git @@ -128,7 +165,7 @@ $ cd skyloft $ git submodule update --init --recursive ``` -### 3.5 Setup Hosts +### 3.6 Setup Hosts Disable CPU frequency scaling so all cores are running at base clock, and setup hugepages: @@ -139,19 +176,6 @@ $ ./disable_cpufreq_scaling.sh -c 0-23 $ sudo ./setup_host.sh ``` -### 3.6 Install DPDK - -Install DPDK v22.11 on the machine: - -```sh -$ git clone https://github.com/yhtzd/dpdk.git -$ cd dpdk -$ meson build -$ cd build -$ ninja -$ sudo meson install -``` - And show the NIC status: ```sh @@ -219,13 +243,21 @@ Each expriment needs different parameters, such as number of CPU cores, preempti ### 4.1 schbench +Before running this experiment, remember to change the cmdline to: + +```config +GRUB_CMDLINE_LINUX="isolcpus=0-23,48-71 nohz_full=0-23,48-71 intel_iommu=off nopat watchdog_thresh=0" +``` + +You can check it through `cat /proc/cmdline`. + The `schbench` experiment shows `Skyloft`'s per-CPU scheduler performance, by comparing the 99% wakeup latency of the `schbench` schduler benchmarking tool. This experiment uses 24 CPU cores, running different number of worker threads, ranging from 8 to 96. The parameters of each build target are listed as follows: -| Build Target | Schedule Policy | Preemption Quantum | -| -------------------- | --------------- | ------------------ | -| schbench-cfs-50us | CFS | 50us | +| Build Target | Schedule Policy | Preemption Quantum | +| ----------------- | --------------- | ------------------ | +| schbench-cfs-50us | CFS | 50us | | schbench-rr-50us | RR | 50us | | schbench-rr-200us | RR | 200us | | schbench-rr-1ms | RR | 1ms | @@ -234,9 +266,9 @@ The parameters of each build target are listed as follows: To run this experiment, take `schbench-cfs-50us` as an example: ```sh -cd skyloft -./scripts/build.sh schbench-cfs-50us -./scripts/bench/schbench.sh cfs-50us +$ cd skyloft +$ ./scripts/build.sh schbench-cfs-50us +$ ./scripts/bench/schbench.sh cfs-50us ``` The results are written into `results_24_cfs-50us` folder. Data from different number of worker threads are summarized in the `all.csv` file, and the output of each run are stored in `.txt` files. @@ -244,16 +276,22 @@ The results are written into `results_24_cfs-50us` folder. Data from different n To plot the figures, move `all.csv` file to the `results/schbench/skyloft_cfs50us` directory (change this path according to the build target), then run the plot script: ```sh -mv results_24_cfs-50us/all.csv results/schbench/skyloft_cfs50us/ -cd scripts/plots -python3 plot_schbench.py -python3 plot_schbench2.py +$ mv results_24_cfs-50us/all.csv results/schbench/skyloft_cfs50us/ +$ cd scripts/plots +$ python3 plot_schbench.py +$ python3 plot_schbench2.py ``` The figures are saved in `scripts/plots/schbench.pdf` and `scripts/plots/schbench2.pdf`, corresponding to the Figure 4 and Figure 5 in the paper. ### 4.2 synthetic-single +Before running this and following experiments, remember to change the cmdline to: + +```config +GRUB_CMDLINE_LINUX="isolcpus=0-21,48-69 nohz_full=0-21,48-69 intel_iommu=off nopat watchdog_thresh=0" +``` + The `run_synthetic_lc.sh` script runs a single synthetic LC app (`shinjuku`), iterating over different target throughput, with the following parameters: - Workers: 20 @@ -263,7 +301,7 @@ The `run_synthetic_lc.sh` script runs a single synthetic LC app (`shinjuku`), it ```sh $ cd skyloft/scripts -$ ./build synthetic-sq +$ ./build.sh synthetic-sq $ ./run_synthetic_lc.sh ``` @@ -288,7 +326,7 @@ The `run_synthetic_lcbe.sh` script runs both a LC app and a BE app (`antagonist` ```sh $ cd skyloft/scripts -$ ./build synthetic-sq_lcbe +$ ./build.sh synthetic-sq_lcbe $ ./run_synthetic_lcbe.sh ``` @@ -316,7 +354,7 @@ Build and run the Skyloft memcached on Server: ```sh $ cd skyloft/scripts -$ ./build memcached +$ ./build.sh memcached $ ./run.sh memcached -p 11211 -t 4 -u root ``` @@ -324,6 +362,7 @@ Run the Shenango client on Client: ```sh $ sudo ./iokerneld +# in another shell $ numactl -N 0 -- \ ./apps/synthetic/target/release/synthetic \ 10.3.3.3:11211 \ @@ -336,26 +375,59 @@ $ numactl -N 0 -- \ --runtime 1000000000 ``` +### 4.5 rocksdb + +Build and run on Server: + +```sh +$ cd skyloft/scripts +# you can run it with different configurations +$ ./build.sh rocksdb-server-5us +# ./build.sh rocksdb-server +# ./build.sh rocksdb-server-20us +# you can also run it with a timer simulated in user space +# ./build.sh rocksdb-server-5us-utimer +$ ./run.sh rocksdb_server 2333 +``` + +Run the Shenango client on Client: + +```sh +$ sudo ./iokerneld +# in another shell +$ numactl -N 0 -- \ + ./apps/synthetic/target/release/synthetic \ + 10.3.3.3:2333 \ + --config client.config \ + --threads 16 \ + --mode runtime-client \ + --protocol synthetic \ + --transport udp \ + --runtime 5000000000 --slowdown --rampup 0 \ + -d rocksdb \ + --mean 1000 --samples 20 --start_mpps 0 --mpps 0.05 +``` + ### 4.6 preempt First, build benchmarks for various preemption mechanism: ```sh -cd microbench -make +$ cd skyloft/scripts +$ ./build.sh microbench ``` Entries in Table 5 can be obtained by running the following commands: -| Entries in Table 5 | Command | -| ------------------ | ------- | -| Signal Send/Recv | `./signal_send_recv` | -| Signal Delivery | `./signal_delivery` | -| User IPI Send/Recv | `./uipi_send_recv` | -| User IPI Delivery | `./uipi_delivery` | -| `setitimer` Recv | `./setitimer_recv` | -| User timer interrupt Recv | `./utimer_recv` | -| Kernel IPI Send/Recv | `./kipi_send_recv` | +| Entries in Table 5 | Command | +| ------------------------- | -------------------- | +| Signal Send/Recv | `./signal_send_recv` | +| Signal Delivery | `./signal_delivery` | +| User IPI Send/Recv | `./uipi_send_recv` | +| User IPI Delivery | `./uipi_delivery` | +| `setitimer` Recv | `./setitimer_recv` | +| User timer interrupt Recv | `./utimer_recv` | +| Kernel IPI Send/Recv | `./kipi_send_recv` | For the Kernel IPI benchmark, you need to get the output of the kernel module by `demsg`: @@ -373,6 +445,16 @@ $ sudo dmesg The send time is `437` cycles, and the receive time is `4370647834 / 2761085 = 1582` cycles. +### 4.7 thread + +Build and run benchmarks for threading microbenchmarks: + +```sh +$ cd skyloft/scripts +$ ./build.sh microbench +$ ./run.sh thread +``` + ## 5. Related Work ### 5.1 ghOSt diff --git a/include/net/ethernet.h b/include/net/ethernet.h index 84da2f6..bcf786c 100644 --- a/include/net/ethernet.h +++ b/include/net/ethernet.h @@ -7,7 +7,7 @@ #pragma once #include -#include + #define ETH_ADDR_LEN 6 #define ETH_TYPE_LEN 2 diff --git a/include/net/icmp.h b/include/net/icmp.h index 05dcf67..8bfcd45 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h @@ -33,7 +33,7 @@ #pragma once #include -#include + /* * Interface Control Message Protocol Definitions. diff --git a/include/net/ip.h b/include/net/ip.h index 6758e53..bd6cffb 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -4,7 +4,7 @@ #include #include -#include + #define MAKE_IP_ADDR(a, b, c, d) \ (((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | (uint32_t)d) diff --git a/include/net/mbuf.h b/include/net/mbuf.h index 8126983..4f5b5d4 100644 --- a/include/net/mbuf.h +++ b/include/net/mbuf.h @@ -13,7 +13,7 @@ #include #include #include -#include + #define MBUF_DEFAULT_LEN 2048 #define MBUF_DEFAULT_HEADROOM 128 diff --git a/include/net/tcp.h b/include/net/tcp.h index ec4c794..35e2269 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -7,7 +7,7 @@ #pragma once #include -#include + typedef uint32_t tcp_seq; diff --git a/include/net/udp.h b/include/net/udp.h index fae7c5d..891f755 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -4,7 +4,7 @@ #pragma once -#include + struct udp_hdr { uint16_t src_port; diff --git a/include/skyloft/io.h b/include/skyloft/io.h index 67f5a9c..0609bae 100644 --- a/include/skyloft/io.h +++ b/include/skyloft/io.h @@ -96,7 +96,7 @@ int str_to_mac(const char *str, struct eth_addr *addr); * I/O thread */ -struct iothread_t { +struct iothread { /* dpdk port id */ int port_id; /* dpdk rx memory pool */ @@ -112,7 +112,7 @@ struct iothread_t { struct eth_addr mac; }; -extern struct iothread_t *io; +extern struct iothread *io; extern physaddr_t* page_paddrs; int iothread_init(void); diff --git a/include/skyloft/mm/slab.h b/include/skyloft/mm/slab.h index d15cdc5..969d065 100644 --- a/include/skyloft/mm/slab.h +++ b/include/skyloft/mm/slab.h @@ -9,7 +9,7 @@ #include #include #include -#include + /* forward declarations */ struct slab_hdr; diff --git a/include/skyloft/mm/tcache.h b/include/skyloft/mm/tcache.h index 209a30e..0c548c9 100644 --- a/include/skyloft/mm/tcache.h +++ b/include/skyloft/mm/tcache.h @@ -10,7 +10,7 @@ #include #include #include -#include + #define TCACHE_MAX_MAG_SIZE 64 #define TCACHE_DEFAULT_MAG_SIZE 8 diff --git a/include/skyloft/platform.h b/include/skyloft/platform.h index 3f0f7aa..0e07c3f 100644 --- a/include/skyloft/platform.h +++ b/include/skyloft/platform.h @@ -32,9 +32,15 @@ static inline int cpu_sibling(int cpu_id) return cpu_siblings[cpu_id]; } -static inline int cpu_numa_node(int cpu_id) { return numa_node_of_cpu(hw_cpu_id(cpu_id)); } +static inline int cpu_numa_node(int cpu_id) +{ + return numa_node_of_cpu(hw_cpu_id(cpu_id)); +} -static inline pid_t _gettid() { return syscall(SYS_gettid); } +static inline pid_t _gettid() +{ + return syscall(SYS_gettid); +} int bind_to_cpu(int tid, int cpu_id); int unbind_cpus(int tid); @@ -63,7 +69,10 @@ physaddr_t mem_virt2phys(void *addr); /* Remote FD */ -static inline int pidfd_open(pid_t pid) { return syscall(SYS_pidfd_open, pid, 0); } +static inline int pidfd_open(pid_t pid) +{ + return syscall(SYS_pidfd_open, pid, 0); +} static inline int pidfd_getfd(int pidfd, int targetfd) { diff --git a/include/skyloft/sched.h b/include/skyloft/sched.h index d091cab..d940915 100644 --- a/include/skyloft/sched.h +++ b/include/skyloft/sched.h @@ -38,8 +38,11 @@ __noreturn void task_exit(void *code); /* assembly helper routines from switch.S */ extern void __context_switch(uint64_t *prev_stack, uint64_t next_stack, uint8_t *prev_stack_busy); +extern void __context_switch_init(uint64_t *prev_stack, uint64_t next_stack, + uint8_t *prev_stack_busy); extern void __context_switch_to_idle(uint64_t *prev_stack, uint64_t idle_stack); extern void __context_switch_from_idle(uint64_t next_stack); +extern void __context_switch_from_idle_init(uint64_t next_stack); extern void __context_switch_to_fn_nosave(void (*fn)(void), uint64_t idle_stack); struct kthread { @@ -56,8 +59,12 @@ struct kthread { int node; /* kernel thread states */ bool parked; - /* RCU generation number */ +#if defined(UTIMER) + int uintr_fd; + uint8_t pad0[24]; +#else uint8_t pad0[28]; +#endif /* 2nd cacheline */ struct mbufq txpktq_overflow; @@ -80,6 +87,7 @@ struct kthread { /* 7th cacheline */ /* statistics counters */ uint64_t stats[STAT_NR]; + } __aligned_cacheline; BUILD_ASSERT(offsetof(struct kthread, txpktq_overflow) == 64); @@ -131,14 +139,20 @@ static __always_inline struct task *task_self() * * Can be nested. */ -static __always_inline void preempt_disable(void) { preempt_cnt++; } +static __always_inline void preempt_disable(void) +{ + preempt_cnt++; +} /** * preempt_enable - reenables preemption * * Can be nested. */ -static __always_inline void preempt_enable(void) { preempt_cnt--; } +static __always_inline void preempt_enable(void) +{ + preempt_cnt--; +} /** * preempt_enabled - returns true if preemption is enabled @@ -162,7 +176,10 @@ static __always_inline __attribute__((target("general-regs-only"))) struct kthre /** * cpuk - returns the per-kernel-thread data of the cpu */ -static inline struct kthread *cpuk(int cpu_id) { return &proc->all_ks[cpu_id]; } +static inline struct kthread *cpuk(int cpu_id) +{ + return &proc->all_ks[cpu_id]; +} /** * getk - returns the per-kernel-thread data and disables preemption @@ -179,14 +196,32 @@ static __always_inline struct kthread *getk(void) /** * putk - reenables preemption after calling getk() */ -static __always_inline void putk(void) { preempt_enable(); } +static __always_inline void putk(void) +{ + preempt_enable(); +} -static inline int current_app_id() { return proc->id; } +static inline int current_app_id() +{ + return proc->id; +} -static inline int current_cpu_id() { return thisk()->cpu; } +static inline int current_cpu_id() +{ + return thisk()->cpu; +} -static inline struct proc *current_app() { return &shm_apps[current_app_id()]; } +static inline struct proc *current_app() +{ + return &shm_apps[current_app_id()]; +} -static inline bool is_daemon() { return current_app_id() == DAEMON_APP_ID; } +static inline bool is_daemon() +{ + return current_app_id() == DAEMON_APP_ID; +} -static inline int current_numa_node() { return thisk()->node; } +static inline int current_numa_node() +{ + return thisk()->node; +} diff --git a/include/skyloft/sched/utimer.h b/include/skyloft/sched/utimer.h new file mode 100644 index 0000000..0d4b05e --- /dev/null +++ b/include/skyloft/sched/utimer.h @@ -0,0 +1,19 @@ +/* + * timer.h: simulated per-CPU timer + */ + +#pragma once + +#include + +#include +#include + +struct utimer { + /* uintr sender index */ + int uintr_index[USED_CPUS]; + /* if cpu has been preempted */ + __nsec deadline[USED_CPUS]; +}; + +__noreturn void utimer_main(void); diff --git a/include/skyloft/sync/timer.h b/include/skyloft/sync/timer.h index 718cb91..e72f65f 100644 --- a/include/skyloft/sync/timer.h +++ b/include/skyloft/sync/timer.h @@ -5,7 +5,7 @@ #pragma once #include -#include + typedef void (*timer_fn_t)(uint64_t arg); diff --git a/include/skyloft/task.h b/include/skyloft/task.h index d4f1475..0d286e1 100644 --- a/include/skyloft/task.h +++ b/include/skyloft/task.h @@ -4,9 +4,9 @@ #pragma once -#include - #include + +#include #include enum task_state { @@ -15,8 +15,8 @@ enum task_state { TASK_BLOCKED, }; -struct switch_frame { - /* callee saved registers */ +/* callee saved regs */ +struct callee_saved { uint64_t rbx; uint64_t rbp; uint64_t r12; @@ -26,6 +26,15 @@ struct switch_frame { uint64_t rdi; /* first argument */ uint64_t rip; }; + +struct switch_frame { +#ifdef SKYLOFT_FXSAVE + struct fxsave fxstate; +#endif + /* points to callee saved regs */ + struct callee_saved callee; +}; + struct stack { union { void *ptr; @@ -51,6 +60,7 @@ struct task { uint8_t stack_busy; bool allow_preempt; bool skip_free; + bool init; uint64_t rsp; uint8_t pad0[16]; /* cache line 1~2 */ @@ -62,7 +72,6 @@ struct task { #define task_is_blocked(t) ((t)->state == TASK_BLOCKED) #define task_is_dead(t) ((t)->state == TASK_DEAD) - struct task *task_create(thread_fn_t fn, void *arg); struct task *task_create_with_buf(thread_fn_t fn, void **buf, size_t buf_len); struct task *task_create_idle(); @@ -76,4 +85,4 @@ int sched_task_init_percpu(void); #else #define TASK_SIZE_PER_APP \ (align_up((sizeof(struct task) + sizeof(struct stack)) * MAX_TASKS_PER_APP, PGSIZE_2MB)) -#endif \ No newline at end of file +#endif diff --git a/libos/io/main.c b/libos/io/main.c index 80609fe..e7cad65 100644 --- a/libos/io/main.c +++ b/libos/io/main.c @@ -19,7 +19,7 @@ #define LOG_INTERVAL_US (3000 * 1000) -struct iothread_t *io; +struct iothread *io; physaddr_t *page_paddrs; int str_to_ip(const char *str, uint32_t *addr) @@ -83,7 +83,7 @@ int iothread_init(void) struct kthread *k; char *ptr; - io = (struct iothread_t *)malloc(sizeof(struct iothread_t)); + io = (struct iothread *)malloc(sizeof(struct iothread)); /* default configurations */ str_to_ip(IO_ADDR, &io->addr); diff --git a/libos/libos.c b/libos/libos.c index 169677b..aa3535d 100644 --- a/libos/libos.c +++ b/libos/libos.c @@ -14,10 +14,12 @@ #include #include #include +#include #include #include #include #include + #include #include #include @@ -107,11 +109,14 @@ int proc_init() proc->pid = getpid(); proc->exited = false; proc->ready = false; -#ifdef SKYLOFT_DPDK - proc->nr_ks = USED_CPUS - 1; -#else proc->nr_ks = USED_CPUS; +#ifdef SKYLOFT_DPDK + proc->nr_ks--; #endif +#ifdef UTIMER + proc->nr_ks--; +#endif +log_debug("nr_ks=%d", proc->nr_ks); for (i = 0; i < USED_CPUS; i++) { struct kthread *k = &proc->all_ks[i]; @@ -134,8 +139,8 @@ int cpubind_init_percpu(void) BUG_ON(skyloft_park_on_cpu(g_logic_cpu_id)); } - log_info("CPU %d(%d): node = %d, tid = %d %p", g_logic_cpu_id, hw_cpu_id(g_logic_cpu_id), - thisk()->node, _gettid(), localk); + log_info("CPU %d(%d): node = %d, tid = %d %p %p", g_logic_cpu_id, hw_cpu_id(g_logic_cpu_id), + thisk()->node, _gettid(), localk, &localk); return 0; } @@ -204,6 +209,11 @@ static __noreturn void *percpu_entry(void *arg) while (atomic_load(&all_init_done) < USED_CPUS); #endif +#ifdef UTIMER + if (cpu_id == UTIMER_CPU) + utimer_main(); +#endif + #ifdef SKYLOFT_DPDK /* CPU reserved for I/O */ if (cpu_id == IO_CPU) { diff --git a/libos/net/mbuf.c b/libos/net/mbuf.c index cc1318b..3efd1bb 100644 --- a/libos/net/mbuf.c +++ b/libos/net/mbuf.c @@ -15,15 +15,14 @@ */ struct mbuf *mbuf_clone(struct mbuf *dst, struct mbuf *src) { - /* copy the backing buffer */ - dst->data = dst->head + mbuf_headroom(src); - memcpy(mbuf_put(dst, mbuf_length(src)), - mbuf_data(src), mbuf_length(src)); + /* copy the backing buffer */ + dst->data = dst->head + mbuf_headroom(src); + memcpy(mbuf_put(dst, mbuf_length(src)), mbuf_data(src), mbuf_length(src)); - /* copy packet metadata */ - dst->csum_type = src->csum_type; - dst->csum = src->csum; - dst->txflags = src->txflags; /* NOTE: this is a union */ + /* copy packet metadata */ + dst->csum_type = src->csum_type; + dst->csum = src->csum; + dst->txflags = src->txflags; /* NOTE: this is a union */ - return dst; + return dst; } diff --git a/libos/net/tcp.h b/libos/net/tcp.h index 7616715..80f33ce 100644 --- a/libos/net/tcp.h +++ b/libos/net/tcp.h @@ -8,7 +8,6 @@ #include #include #include -#include #include "waitq.h" diff --git a/libos/platform/mem.c b/libos/platform/mem.c index 63434ba..25bf5f3 100644 --- a/libos/platform/mem.c +++ b/libos/platform/mem.c @@ -23,7 +23,10 @@ long mbind(void *start, size_t len, int mode, const unsigned long *nmask, unsign return syscall(__NR_mbind, start, len, mode, nmask, maxnode, flags); } -static void sigbus_error(int sig) { panic("couldn't map pages"); } +static void sigbus_error(int sig) +{ + panic("couldn't map pages"); +} void touch_mapping(void *base, size_t len, size_t pgsize) { diff --git a/libos/platform/uintr.c b/libos/platform/uintr.c index f10a44e..011570c 100644 --- a/libos/platform/uintr.c +++ b/libos/platform/uintr.c @@ -2,7 +2,9 @@ #include #include +#include #include + #include #include @@ -17,12 +19,28 @@ int platform_uintr_init_percpu(void) return 0; #endif +#ifdef UTIMER + if (sl_current_cpu_id() == UTIMER_CPU) + return 0; +#endif + int ret = uintr_register_handler(uintr_handler, 0); if (ret < 0) { log_err("uintr: failed to register a handler %d", ret); return -1; } +#ifdef UTIMER + int uintr_fd = uintr_vector_fd(1, 0); + if (uintr_fd < 0) { + log_err("uintr: failed to register interrupt vector\n"); + return -1; + } + + thisk()->uintr_fd = uintr_fd; + local_irq_disable(); + log_info("uintr: CPU %d registered uintr receiver", sl_current_cpu_id()); +#else g_uintr_index = uintr_register_self(UVEC, 0); if (g_uintr_index < 0) { log_err("uintr: failed to register the sender for self"); @@ -45,6 +63,7 @@ int platform_uintr_init_percpu(void) _senduipi(g_uintr_index); log_info("uintr: CPU %d registered uintr index %d", sl_current_cpu_id(), g_uintr_index); +#endif return 0; } diff --git a/libos/sched/policy/fifo.c b/libos/sched/policy/fifo.c index 83e917f..248a9d4 100644 --- a/libos/sched/policy/fifo.c +++ b/libos/sched/policy/fifo.c @@ -59,9 +59,15 @@ int fifo_sched_spawn(struct task *task, int cpu) return 0; } -void fifo_sched_yield() { put_task(this_rq(), task_self()); } +void fifo_sched_yield() +{ + put_task(this_rq(), task_self()); +} -void fifo_sched_wakeup(struct task *task) { put_task(this_rq(), task); } +void fifo_sched_wakeup(struct task *task) +{ + put_task(this_rq(), task); +} static bool steal_task(struct fifo_rq *l, struct fifo_rq *r) { @@ -106,6 +112,14 @@ static bool steal_task(struct fifo_rq *l, struct fifo_rq *r) return task != NULL; } +#if defined(SKYLOFT_DPDK) && defined(UTIMER) +#define WORKER_CPUS (USED_CPUS - 2) +#elif !defined(SKYLOFT_DPDK) && !defined(UTIMER) +#define WORKER_CPUS (USED_CPUS) +#else +#define WORKER_CPUS (USED_CPUS - 1) +#endif + void fifo_sched_balance() { int cpu = current_cpu_id(); @@ -124,8 +138,8 @@ void fifo_sched_balance() /* try to steal from every kthread */ start_idx = rand_crc32c((uintptr_t)l); - for (i = 0; i < USED_CPUS - 1; i++) { - idx = (start_idx + i) % (USED_CPUS - 1); + for (i = 0; i < WORKER_CPUS; i++) { + idx = (start_idx + i) % WORKER_CPUS; if (idx != cpu && steal_task(l, cpu_rq(idx))) return; } diff --git a/libos/sched/policy/rr.c b/libos/sched/policy/rr.c index ac9cc3b..d2f4a64 100644 --- a/libos/sched/policy/rr.c +++ b/libos/sched/policy/rr.c @@ -65,7 +65,10 @@ int fifo_sched_spawn(struct task *task, int cpu) return 0; } -void fifo_sched_yield() { put_task(this_rq(), task_self()); } +void fifo_sched_yield() +{ + put_task(this_rq(), task_self()); +} void fifo_sched_wakeup(struct task *task) { diff --git a/libos/sched/sched.c b/libos/sched/sched.c index 5e0d3e1..0d82948 100644 --- a/libos/sched/sched.c +++ b/libos/sched/sched.c @@ -109,7 +109,11 @@ static __always_inline void fast_schedule() /* switch stacks and enter the next task */ __curr = next; - __context_switch(&prev->rsp, next->rsp, &prev->stack_busy); + if (next->init) { + next->init = false; + __context_switch_init(&prev->rsp, next->rsp, &prev->stack_busy); + } else + __context_switch(&prev->rsp, next->rsp, &prev->stack_busy); } /** @@ -152,7 +156,7 @@ __noreturn __noinline void schedule() /* optional load balance */ __sched_balance(); #ifdef SKYLOFT_SCHED_CFS - __sched_percpu_lock(g_logic_cpu_id); + __sched_percpu_lock(g_logic_cpu_id); #endif #endif goto again; @@ -187,7 +191,11 @@ __noreturn __noinline void schedule() /* switch stacks and enter the next task */ __curr = next; - __context_switch_from_idle(next->rsp); + if (next->init) { + next->init = false; + __context_switch_from_idle_init(next->rsp); + } else + __context_switch_from_idle(next->rsp); } __noreturn void start_schedule(void) @@ -392,13 +400,25 @@ __noreturn void task_exit(void *code) /* API implementations */ -const char *__api sl_sched_policy_name() { return __sched_name; } +const char *__api sl_sched_policy_name() +{ + return __sched_name; +} -int __api sl_current_task_id() { return -1; } +int __api sl_current_task_id() +{ + return __curr->id; +} -int __api sl_sched_set_params(void *params) { return __sched_set_params(params); } +int __api sl_sched_set_params(void *params) +{ + return __sched_set_params(params); +} -void __api sl_sched_poll() { __sched_poll(); } +void __api sl_sched_poll() +{ + __sched_poll(); +} int __api sl_task_spawn(thread_fn_t fn, void *arg, int stack_size) { @@ -410,11 +430,20 @@ int __api sl_task_spawn_oncpu(int cpu_id, thread_fn_t fn, void *arg, int stack_s return task_spawn(cpu_id, fn, arg, stack_size); } -void __api sl_task_yield() { task_yield(); } +void __api sl_task_yield() +{ + task_yield(); +} -__noreturn void __api sl_task_exit(void *code) { task_exit(code); } +__noreturn void __api sl_task_exit(void *code) +{ + task_exit(code); +} -void __api sl_dump_tasks() { __sched_dump_tasks(); } +void __api sl_dump_tasks() +{ + __sched_dump_tasks(); +} #ifdef SKYLOFT_UINTR @@ -422,11 +451,10 @@ void __attribute__((target("general-regs-only"))) __attribute__((interrupt)) uintr_handler(struct __uintr_frame *ui_frame, unsigned long long vector) { /* reset UPID.PIR */ -#ifdef SCHED_PERCPU +#if defined(SCHED_PERCPU) && !defined(UTIMER) _senduipi(uintr_index()); #endif ADD_STAT(UINTR, 1); - // softirq_run(SOFTIRQ_MAX_BUDGET); /* check if rescheduling needed */ if (__sched_preempt()) { if (preempt_enabled() && __curr->allow_preempt) { diff --git a/libos/sched/softirq.c b/libos/sched/softirq.c index bd05193..2e3eccb 100644 --- a/libos/sched/softirq.c +++ b/libos/sched/softirq.c @@ -14,7 +14,6 @@ #include #include #include -#include struct softirq_work { /* packets received */ diff --git a/libos/sched/switch.S b/libos/sched/switch.S index 520de10..c729e22 100644 --- a/libos/sched/switch.S +++ b/libos/sched/switch.S @@ -1,10 +1,29 @@ .intel_syntax noprefix .text -.align 16 -.globl __context_switch -.type __context_switch, @function -__context_switch: +#ifdef SKYLOFT_FXSAVE + +.macro SAVE_FXSTATE + sub rsp, 512 + fxsave64 [rsp] +.endm + +.macro RESTORE_FXSTATE + fxrstor64 [rsp] + add rsp, 512 +.endm + +#else + +.macro SAVE_FXSTATE +.endm + +.macro RESTORE_FXSTATE +.endm + +#endif + +.macro SAVE_CALLEE push rdi push r15 push r14 @@ -12,12 +31,9 @@ __context_switch: push r12 push rbp push rbx - mov [rdi], rsp - - /* clear the stack busy flag */ - mov byte ptr [rdx], 0 +.endm - mov rsp, rsi +.macro RESTORE_CALLEE pop rbx pop rbp pop r12 @@ -25,6 +41,46 @@ __context_switch: pop r14 pop r15 pop rdi +.endm + +.align 16 +.globl __context_switch +.type __context_switch, @function +__context_switch: + SAVE_CALLEE + SAVE_FXSTATE + + mov [rdi], rsp + + /* clear the stack busy flag */ + mov byte ptr [rdx], 0 + + mov rsp, rsi + + RESTORE_FXSTATE + RESTORE_CALLEE +#ifdef SKYLOFT_UINTR + /* enable preemption */ + stui +#endif + ret + +.align 16 +.globl __context_switch_init +.type __context_switch_init, @function +__context_switch_init: + SAVE_CALLEE + SAVE_FXSTATE + + mov [rdi], rsp + + /* clear the stack busy flag */ + mov byte ptr [rdx], 0 + + mov rsp, rsi + + /* without fxstate */ + RESTORE_CALLEE #ifdef SKYLOFT_UINTR /* enable preemption */ stui @@ -36,13 +92,21 @@ __context_switch: .type __context_switch_from_idle, @function __context_switch_from_idle: mov rsp, rdi - pop rbx - pop rbp - pop r12 - pop r13 - pop r14 - pop r15 - pop rdi + RESTORE_FXSTATE + RESTORE_CALLEE +#ifdef SKYLOFT_UINTR + /* enable preemption */ + stui +#endif + ret + +.align 16 +.globl __context_switch_from_idle_init +.type __context_switch_from_idle_init, @function +__context_switch_from_idle_init: + mov rsp, rdi + /* without fxstate */ + RESTORE_CALLEE #ifdef SKYLOFT_UINTR /* enable preemption */ stui @@ -53,13 +117,8 @@ __context_switch_from_idle: .globl __context_switch_to_idle .type __context_switch_to_idle, @function __context_switch_to_idle: - push rdi - push r15 - push r14 - push r13 - push r12 - push rbp - push rbx + SAVE_CALLEE + SAVE_FXSTATE mov [rdi], rsp mov rsp, rsi @@ -71,3 +130,17 @@ __context_switch_to_idle: __context_switch_to_fn_nosave: mov rsp, rsi jmp rdi + +.align 16 +.globl __context_switch_to_idle_and_run +.type __context_switch_to_idle_and_run, @function +__context_switch_to_idle_and_run: + SAVE_CALLEE + SAVE_FXSTATE + mov [rdi], rsp # arg1: prev rsp + + mov rsp, [rsi] # arg2: next rsp + mov rdi, rcx # arg4: fn_arg + and rsp, -16 + call rdx # arg3: fn + call schedule diff --git a/libos/sched/task.c b/libos/sched/task.c index bc33122..efbb7bf 100644 --- a/libos/sched/task.c +++ b/libos/sched/task.c @@ -1,4 +1,3 @@ -#include "skyloft/sched.h" #include #include @@ -10,6 +9,7 @@ #include #include #include +#include #include #include @@ -25,6 +25,7 @@ static __always_inline void __task_init(struct task *t, struct stack *s) t->state = TASK_RUNNABLE; t->allow_preempt = false; t->skip_free = false; + t->init = true; #if DEBUG t->id = atomic_inc(&task_id_allocator); #endif @@ -157,7 +158,10 @@ static __always_inline int __task_alloc_init(void *base) return 0; } -static __always_inline int __task_alloc_init_percpu() { return 0; } +static __always_inline int __task_alloc_init_percpu() +{ + return 0; +} #endif @@ -165,7 +169,7 @@ struct task *task_create(thread_fn_t fn, void *arg) { uint64_t *rsp; struct task *task; - struct switch_frame *frame; + struct callee_saved *frame; task = __task_create(false); if (unlikely(!task)) @@ -173,7 +177,7 @@ struct task *task_create(thread_fn_t fn, void *arg) rsp = (uint64_t *)stack_top(task->stack); *--rsp = (uint64_t)task_exit; - frame = (struct switch_frame *)rsp - 1; + frame = (struct callee_saved *)rsp - 1; frame->rip = (uint64_t)fn; frame->rdi = (uint64_t)arg; frame->rbp = 0; @@ -186,7 +190,7 @@ struct task *task_create_with_buf(thread_fn_t fn, void **buf, size_t buf_len) { uint64_t rsp, *ptr; - struct switch_frame *frame; + struct callee_saved *frame; struct task *task = __task_create(false); if (unlikely(!task)) @@ -196,9 +200,10 @@ struct task *task_create_with_buf(thread_fn_t fn, void **buf, size_t buf_len) rsp -= buf_len; rsp = align_down(rsp, RSP_ALIGNMENT); *buf = (void *)rsp; + ptr = (uint64_t *)rsp; *--ptr = (uint64_t)task_exit; - frame = (struct switch_frame *)ptr - 1; + frame = (struct callee_saved *)ptr - 1; frame->rip = (uint64_t)fn; frame->rdi = (uint64_t)*buf; frame->rbp = 0; @@ -229,7 +234,10 @@ void task_free(struct task *t) log_debug("%s %p %p %d", __func__, t, t->stack, t->id); } -int sched_task_init_percpu() { return __task_alloc_init_percpu(); } +int sched_task_init_percpu() +{ + return __task_alloc_init_percpu(); +} int sched_task_init(void *base) { diff --git a/libos/sched/utimer.c b/libos/sched/utimer.c new file mode 100644 index 0000000..b8b967c --- /dev/null +++ b/libos/sched/utimer.c @@ -0,0 +1,51 @@ +#include +#include +#include + +#include +#include +#include + +#ifdef UTIMER + +#define NSEC_PER_TICK (NSEC_PER_SEC / TIMER_HZ) + +static struct utimer utimer; + +static int utimer_init(void) +{ + int i, ret; + + for (i = 0; i < proc->nr_ks; i++) { + ret = uintr_register_sender(proc->all_ks[i].uintr_fd, 0); + if (ret < 0) { + log_err("%s: failed to register uintr sender to %d", __func__, i); + return ret; + } + + utimer.uintr_index[i] = ret; + utimer.deadline[i] = now_ns() + NSEC_PER_TICK; + } + + return 0; +} + +__noreturn void utimer_main(void) +{ + int i; + + utimer_init(); + + log_info("utimer: initialized on CPU %d(%d)", current_cpu_id(), hw_cpu_id(current_cpu_id())); + + while (true) { + for (i = 0; i < proc->nr_ks; i++) { + if (now_ns() > utimer.deadline[i]) { + _senduipi(utimer.uintr_index[i]); + utimer.deadline[i] = now_ns() + NSEC_PER_TICK; + } + } + } +} + +#endif \ No newline at end of file diff --git a/libos/shim/pthread.c b/libos/shim/pthread.c index 779e2a5..be24915 100644 --- a/libos/shim/pthread.c +++ b/libos/shim/pthread.c @@ -110,7 +110,10 @@ pthread_t sl_pthread_self() return align_down(stack_top(task_self()->stack) - sizeof(struct join_handle), RSP_ALIGNMENT); } -void __attribute__((noreturn)) sl_pthread_exit(void *retval) { task_exit(retval); } +void __attribute__((noreturn)) sl_pthread_exit(void *retval) +{ + task_exit(retval); +} int sl_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr) { @@ -135,7 +138,10 @@ int sl_pthread_mutex_unlock(pthread_mutex_t *mutex) return 0; } -int sl_pthread_mutex_destroy(pthread_mutex_t *mutex) { return 0; } +int sl_pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + return 0; +} int sl_pthread_cond_init(pthread_cond_t *__restrict cond, const pthread_condattr_t *__restrict cond_attr) @@ -162,4 +168,7 @@ int sl_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) return 0; } -int sl_pthread_cond_destroy(pthread_cond_t *cond) { return 0; } \ No newline at end of file +int sl_pthread_cond_destroy(pthread_cond_t *cond) +{ + return 0; +} \ No newline at end of file diff --git a/libos/stat.c b/libos/stat.c index be33c22..f4db6a6 100644 --- a/libos/stat.c +++ b/libos/stat.c @@ -1,9 +1,9 @@ #include -#include -#include #include #include +#include +#include void print_stats(void) { diff --git a/libos/sync/timer.c b/libos/sync/timer.c index 58a02fc..a798b8d 100644 --- a/libos/sync/timer.c +++ b/libos/sync/timer.c @@ -245,7 +245,10 @@ bool timer_cancel(struct timer_entry *e) return true; } -static void timer_finish_sleep(unsigned long arg) { task_wakeup((struct task *)arg); } +static void timer_finish_sleep(unsigned long arg) +{ + task_wakeup((struct task *)arg); +} static void __timer_sleep(uint64_t deadline_us) { @@ -281,11 +284,20 @@ void timer_sleep_until(uint64_t deadline_us) * timer_sleep - sleeps for a duration * @duration_us: the duration time in microseconds */ -void timer_sleep(uint64_t duration_us) { __timer_sleep(now_us() + duration_us); } +void timer_sleep(uint64_t duration_us) +{ + __timer_sleep(now_us() + duration_us); +} -void __api sl_sleep(int secs) { return timer_sleep(secs * USEC_PER_SEC); } +void __api sl_sleep(int secs) +{ + return timer_sleep(secs * USEC_PER_SEC); +} -void __api sl_usleep(int usecs) { return timer_sleep(usecs); } +void __api sl_usleep(int usecs) +{ + return timer_sleep(usecs); +} /** * timer_softirq - handles expired timers diff --git a/microbench/.gitignore b/microbench/.gitignore index c06c6e9..46b7823 100644 --- a/microbench/.gitignore +++ b/microbench/.gitignore @@ -5,3 +5,5 @@ signal_send_recv signal_delivery setitimer_recv kipi_send_recv +fxsave +thread diff --git a/microbench/Makefile b/microbench/Makefile index 9a3ed50..b712de4 100644 --- a/microbench/Makefile +++ b/microbench/Makefile @@ -1,15 +1,29 @@ CC := gcc +SKYLOFT_DIR ?= + CFLAGS += -Wall -g -D_GNU_SOURCE -DSKYLOFT_UINTR -muintr -O3 CFLAGS += -I../utils/include -I../include -LDLIBS += -lpthread +LDLIBS += $(SKYLOFT_DIR)/lib/libskyloft.a $(SKYLOFT_DIR)/lib/libutils.a +LDFLAGS += -T $(SKYLOFT_DIR)/lib/libos.ld -lnuma -lpthread +LDFLAGS += $(shell pkg-config --libs libdpdk) -TARGETS := uipi_send_recv uipi_delivery utimer_recv signal_send_recv signal_delivery setitimer_recv kipi_send_recv +TARGETS := \ + uipi_send_recv \ + uipi_delivery \ + utimer_recv \ + signal_send_recv \ + signal_delivery \ + setitimer_recv \ + kipi_send_recv \ + fxsave \ + thread all: $(TARGETS) + ln -sf ./thread ../build/bin/thread %: %.c - $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) $(LDFLAGS) clean: rm -rf $(TARGETS) diff --git a/microbench/common.h b/microbench/common.h index ee8a9af..1a029df 100644 --- a/microbench/common.h +++ b/microbench/common.h @@ -1,9 +1,24 @@ #pragma once +#include + +#include + #define DIV_ROUND(sum, count) (((sum) + (count) / 2) / (count)) -static inline void dummy_work(uint64_t iter) { +static inline void dummy_work(uint64_t iter) +{ while (iter--) { asm volatile("nop"); } } + +static void bench_one(const char *name, void(bench_fn)(), int rounds) +{ + __nsec before = now_ns(); + bench_fn(); + __nsec after = now_ns(); + __nsec elapsed = (after - before + rounds / 2) / rounds; + + printf("%s: %ldns (%ld / %d)\n", name, elapsed, after - before, rounds); +} diff --git a/microbench/fxsave.c b/microbench/fxsave.c new file mode 100644 index 0000000..1c0851d --- /dev/null +++ b/microbench/fxsave.c @@ -0,0 +1,50 @@ +#include +#include + +#include +#include +#include +#include + +#define ITER 100000 + +struct fxsave fxstate __attribute__((aligned(16))); + +void __always_inline fxsave() +{ + __asm__("fxsave64 (%0)" : : "r"(&fxstate)); +} + +void __always_inline fxrstor() +{ + __asm__("fxrstor64 (%0)" : : "r"(&fxstate)); +} + +int main() +{ + int i; + uint64_t tsc; + + bind_to_cpu(2); + + tsc = now_tsc(); + for (i = 0; i < ITER; i++) { + fxsave(); + } + printf("fxsave %.3lf cycles\n", (double)(now_tsc() - tsc) / ITER); + + tsc = now_tsc(); + for (i = 0; i < ITER; i++) { + fxrstor(); + } + printf("fxrstor %.3lf cycles\n", (double)(now_tsc() - tsc) / ITER); + + tsc = now_tsc(); + for (i = 0; i < ITER; i++) { + fxsave(); + fxrstor(); + } + printf("fxsave + fxrstor %.3lf cycles\n", (double)(now_tsc() - tsc) / ITER); + + return 0; +} \ No newline at end of file diff --git a/microbench/thread.c b/microbench/thread.c new file mode 100644 index 0000000..4719594 --- /dev/null +++ b/microbench/thread.c @@ -0,0 +1,109 @@ +#include +#include + +#include +#include +#include + +#include + +#include "common.h" +#include "skyloft/sync/sync.h" + +#define ROUNDS 10000000 +#define ROUNDS2 10000 + +static atomic_int counter = 0; + +static void null_fn(void *) +{ + atomic_fetch_add(&counter, 1); +} + +static void thread_yield_fn(void *) +{ + for (int i = 0; i < ROUNDS / 2; ++i) sl_task_yield(); + atomic_fetch_add(&counter, 1); +} + +static void bench_spawn() +{ + for (int i = 0; i < ROUNDS; ++i) { + atomic_store(&counter, 0); + sl_task_spawn(null_fn, NULL, 0); + sl_task_yield(); + } +} + +static void bench_yield() +{ + atomic_store(&counter, 0); + + sl_task_spawn(thread_yield_fn, NULL, 0); + thread_yield_fn(NULL); + + while (atomic_load(&counter) < 2) { + sl_task_yield(); + } +} + +static void bench_mutex() +{ + mutex_t m; + volatile unsigned long foo = 0; + + mutex_init(&m); + + for (int i = 0; i < ROUNDS; ++i) { + mutex_lock(&m); + foo++; + mutex_unlock(&m); + } +} + +mutex_t m; +condvar_t cv; +bool dir = false; + +static void thread_ping_fn(void *) +{ + mutex_lock(&m); + for (int i = 0; i < ROUNDS / 2; ++i) { + while (dir) condvar_wait(&cv, &m); + dir = true; + condvar_signal(&cv); + } + mutex_unlock(&m); +} + +static void bench_condvar() +{ + mutex_init(&m); + condvar_init(&cv); + + sl_task_spawn(thread_ping_fn, NULL, 0); + + mutex_lock(&m); + for (int i = 0; i < ROUNDS / 2; ++i) { + while (!dir) condvar_wait(&cv, &m); + dir = false; + condvar_signal(&cv); + } + mutex_unlock(&m); + + sl_task_yield(); +} + +void app_main(void *arg) +{ + bench_one("yield", bench_yield, ROUNDS); + bench_one("spawn", bench_spawn, ROUNDS); + bench_one("mutex", bench_mutex, ROUNDS); + bench_one("condvar", bench_condvar, ROUNDS); +} + +int main(int argc, char *argv[]) +{ + printf("Skyloft threading microbenchmark\n"); + sl_libos_start(app_main, NULL); +} diff --git a/paper_results/rocksdb/50-get-50-scan/shenango b/paper_results/rocksdb/50-get-50-scan/shenango new file mode 100644 index 0000000..6c79410 --- /dev/null +++ b/paper_results/rocksdb/50-get-50-scan/shenango @@ -0,0 +1,19 @@ +rocksdb, 2482, 2482, 0, 12, 11.7, 26.1, 29.9, 43.3, 57.6, 1713378553 +rocksdb, 5045, 5045, 0, 13, 2.0, 26.5, 30.0, 39.2, 47.2, 1713378564 +rocksdb, 7468, 7468, 0, 0, 11.8, 26.8, 31.1, 38.3, 46.0, 1713378574 +rocksdb, 10074, 10074, 0, 2, 11.6, 26.8, 31.8, 38.5, 44.8, 1713378585 +rocksdb, 12577, 12577, 0, 1, 11.7, 27.1, 32.7, 38.9, 47.4, 1713378595 +rocksdb, 15079, 15079, 0, 5, 11.3, 26.7, 32.6, 39.1, 47.7, 1713378606 +rocksdb, 17526, 17526, 0, 2, 1.2, 27.1, 33.7, 42.4, 134.4, 1713378617 +rocksdb, 19981, 19981, 0, 2, 11.5, 27.0, 34.0, 52.3, 170.8, 1713378627 +rocksdb, 22453, 22453, 0, 40, 11.6, 27.2, 35.1, 108.8, 271.0, 1713378638 +rocksdb, 25071, 25071, 0, 2, 1.5, 27.4, 39.2, 213.0, 429.6, 1713378649 +rocksdb, 27463, 27463, 0, 49, 1.8, 27.6, 72.6, 274.7, 500.1, 1713378659 +rocksdb, 29907, 29907, 0, 25, 11.5, 27.8, 126.0, 393.5, 794.8, 1713378670 +rocksdb, 32355, 32355, 0, 8, 11.5, 28.5, 198.1, 493.2, 813.8, 1713378681 +rocksdb, 35057, 35057, 0, 4, 2.1, 31.7, 286.7, 640.1, 1050.2, 1713378691 +rocksdb, 37536, 37536, 0, 5, 11.5, 58.8, 432.2, 878.2, 1388.5, 1713378702 +rocksdb, 39961, 39961, 0, 3, 3.1, 123.2, 661.4, 1311.0, 1934.8, 1713378713 +rocksdb, 42690, 42690, 0, 6, 11.8, 254.0, 1118.7, 2219.1, 3833.8, 1713378723 +rocksdb, 44843, 44843, 0, 3, 12.0, 669.7, 2685.6, 5796.3, 9386.2, 1713378734 +rocksdb, 47484, 47484, 0, 4, 379.2, 15167.0, 284413.0, 305083.3, 310982.5, 1713378745 diff --git a/paper_results/rocksdb/50-get-50-scan/skyloft_100us b/paper_results/rocksdb/50-get-50-scan/skyloft_100us new file mode 100644 index 0000000..e76b0e7 --- /dev/null +++ b/paper_results/rocksdb/50-get-50-scan/skyloft_100us @@ -0,0 +1,10 @@ +rocksdb, 4999, 4999, 0, 20, 12.2, 14.4, 17.2, 25.9, 64.8, 1713363491 +rocksdb, 10008, 10008, 0, 22, 1.1, 14.2, 16.8, 19.7, 37.3, 1713363501 +rocksdb, 15033, 15033, 0, 21, 11.9, 14.1, 16.6, 19.4, 45.0, 1713363512 +rocksdb, 19959, 19959, 0, 31, 11.8, 13.9, 16.6, 39.3, 131.8, 1713363523 +rocksdb, 25042, 25042, 0, 4, 1.2, 13.8, 18.1, 91.8, 167.6, 1713363533 +rocksdb, 30009, 30009, 0, 1, 11.7, 13.9, 69.7, 150.8, 238.0, 1713363544 +rocksdb, 34993, 34993, 0, 5, 11.5, 16.8, 116.5, 266.6, 406.1, 1713363554 +rocksdb, 39984, 39984, 0, 4, 11.5, 68.4, 237.5, 468.1, 784.6, 1713363565 +rocksdb, 45024, 45024, 0, 6, 11.8, 224.0, 785.9, 1578.7, 2511.7, 1713363576 +rocksdb, 49977, 49713, 1188, 59, 250.5, 1790.1, 2460474.0, inf, inf, 1713363587 diff --git a/paper_results/rocksdb/50-get-50-scan/skyloft_10us b/paper_results/rocksdb/50-get-50-scan/skyloft_10us new file mode 100644 index 0000000..6bd2fde --- /dev/null +++ b/paper_results/rocksdb/50-get-50-scan/skyloft_10us @@ -0,0 +1,26 @@ +rocksdb, 2456, 2456, 0, 4, 12.2, 14.4, 17.4, 24.9, 44.1, 1713375429 +rocksdb, 5032, 5032, 0, 1, 12.1, 14.4, 17.8, 19.9, 23.0, 1713372851 +rocksdb, 7518, 7518, 0, 0, 1.6, 14.2, 16.8, 18.9, 23.4, 1713372861 +rocksdb, 9971, 9971, 0, 0, 12.0, 14.1, 16.5, 18.7, 20.8, 1713372872 +rocksdb, 12637, 12637, 0, 3, 1.5, 14.1, 16.7, 19.2, 23.9, 1713372883 +rocksdb, 15015, 15015, 0, 4, 1.5, 14.0, 16.5, 19.4, 21.7, 1713372893 +rocksdb, 17478, 17478, 0, 4, 1.4, 13.9, 16.4, 19.9, 25.6, 1713372910 +rocksdb, 19880, 19880, 0, 8, 11.5, 14.0, 16.9, 21.6, 31.4, 1713372921 +rocksdb, 22517, 22517, 0, 3, 11.8, 13.9, 17.0, 22.2, 31.3, 1713372931 +rocksdb, 25043, 25043, 0, 3, 1.4, 13.8, 18.7, 26.6, 35.3, 1713372942 +rocksdb, 27433, 27433, 0, 6, 1.6, 13.9, 20.6, 31.0, 45.0, 1713372953 +rocksdb, 29935, 29935, 0, 5, 1.7, 14.1, 22.7, 37.8, 51.1, 1713372963 +rocksdb, 32634, 32634, 0, 5, 3.8, 14.6, 26.6, 41.2, 60.9, 1713372974 +rocksdb, 35029, 35029, 0, 3, 3.4, 16.7, 32.3, 52.7, 73.8, 1713372985 +rocksdb, 37573, 37573, 0, 3, 5.6, 19.9, 42.5, 73.8, 105.5, 1713372996 +rocksdb, 39966, 39966, 0, 6, 5.1, 22.8, 55.9, 101.1, 153.1, 1713373006 +rocksdb, 42502, 42502, 0, 74, 11.6, 37.5, 102.5, 189.5, 289.6, 1713375273 +rocksdb, 44908, 44908, 0, 24, 16.5, 126.9, 320.9, 1107.3, 184968.5, 1713375130 +rocksdb, 47598, 47598, 0, 3, 37.1, 282.4, 5979.2, 7667.2, 4175177.8, 1713373038 +rocksdb, 50002, 49616, 1737, 9, 73.8, 324.8, 7857.2, inf, inf, 1713373049 + +rocksdb, 42690, 42690, 0, 104, 11.7, 42.1, 134.5, 262.3, 327.6, 1713375119 +rocksdb, 44908, 44908, 0, 24, 16.5, 126.9, 320.9, 1107.3, 184968.5, 1713375130 +rocksdb, 47503, 47503, 0, 21, 39.3, 290.8, 5917.3, 7595.2, 3872584.2, 1713375141 +rocksdb, 49994, 49556, 1970, 26, 40.7, 324.4, 1612571.9, inf, inf, 1713375151 + diff --git a/paper_results/rocksdb/50-get-50-scan/skyloft_20us b/paper_results/rocksdb/50-get-50-scan/skyloft_20us new file mode 100644 index 0000000..71c5946 --- /dev/null +++ b/paper_results/rocksdb/50-get-50-scan/skyloft_20us @@ -0,0 +1,20 @@ +rocksdb, 2471, 2471, 0, 4, 12.2, 14.4, 18.9, 31.0, 39.2, 1724561378 +rocksdb, 5001, 5001, 0, 0, 11.9, 14.3, 17.9, 22.8, 42.3, 1724561389 +rocksdb, 7448, 7448, 0, 11, 1.3, 14.2, 17.5, 22.5, 39.3, 1724561399 +rocksdb, 10049, 10049, 0, 0, 11.9, 14.1, 17.1, 20.2, 24.5, 1724561410 +rocksdb, 12488, 12488, 0, 0, 1.3, 14.1, 16.9, 19.8, 27.9, 1724561421 +rocksdb, 15030, 15030, 0, 0, 1.3, 14.0, 16.9, 19.8, 130.6, 1724561431 +rocksdb, 17456, 17456, 0, 19, 1.2, 14.0, 16.9, 21.8, 32.8, 1724561442 +rocksdb, 19955, 19955, 0, 1, 1.2, 13.8, 16.8, 24.4, 34.4, 1724561452 +rocksdb, 22352, 22352, 0, 1, 11.6, 13.8, 17.2, 30.8, 50.9, 1724561468 +rocksdb, 25115, 25115, 0, 1, 11.6, 13.8, 19.5, 42.1, 63.6, 1724561479 +rocksdb, 27556, 27556, 0, 1, 1.5, 13.8, 26.2, 48.6, 72.8, 1724561489 +rocksdb, 30152, 30152, 0, 0, 11.6, 13.9, 31.1, 53.2, 86.3, 1724561500 +rocksdb, 32453, 32453, 0, 35, 2.1, 14.6, 37.4, 67.8, 98.9, 1724561511 +rocksdb, 34969, 34969, 0, 0, 2.2, 17.2, 49.3, 92.8, 171.7, 1724561521 +rocksdb, 37562, 37562, 0, 0, 3.4, 23.7, 59.6, 106.7, 163.5, 1724561532 +rocksdb, 39932, 39932, 0, 1, 9.6, 29.7, 79.5, 154.5, 275.0, 1724561543 +rocksdb, 42523, 42523, 0, 2, 7.1, 52.4, 160.8, 279.3, 394.9, 1724561554 +rocksdb, 44945, 44945, 0, 1, 12.0, 110.1, 343.3, 594.7, 662.0, 1724561564 +rocksdb, 47296, 47296, 0, 1, 32.2, 385.3, 5211.8, 7675.7, 4405283.0, 1724561575 +rocksdb, 49994, 49994, 0, 0, 76.7, 592.7, 6850.9, 3027007.8, 4616004.5, 1724561586 \ No newline at end of file diff --git a/paper_results/rocksdb/50-get-50-scan/skyloft_5us b/paper_results/rocksdb/50-get-50-scan/skyloft_5us new file mode 100644 index 0000000..747aa39 --- /dev/null +++ b/paper_results/rocksdb/50-get-50-scan/skyloft_5us @@ -0,0 +1,18 @@ +ocksdb, 2496, 2496, 0, 5, 12.2, 15.0, 23.6, 34.9, 44.4, 1724560568 +rocksdb, 5016, 5016, 0, 0, 12.2, 14.9, 20.6, 27.9, 44.6, 1724560579 +rocksdb, 7495, 7495, 0, 14, 12.0, 14.7, 19.4, 26.9, 35.5, 1724560589 +rocksdb, 10000, 10000, 0, 19, 2.2, 14.7, 18.9, 25.9, 38.6, 1724560600 +rocksdb, 12489, 12489, 0, 0, 2.0, 14.5, 18.1, 23.2, 29.6, 1724560611 +rocksdb, 14978, 14978, 0, 1, 1.9, 14.4, 17.7, 22.3, 30.1, 1724560621 +rocksdb, 17553, 17553, 0, 4, 1.8, 14.3, 17.6, 21.0, 26.8, 1724560632 +rocksdb, 20035, 20035, 0, 0, 11.8, 14.3, 17.4, 21.3, 28.8, 1724560643 +rocksdb, 22569, 22569, 0, 0, 1.6, 14.1, 17.2, 21.0, 27.1, 1724560653 +rocksdb, 25142, 25142, 0, 0, 1.7, 14.1, 17.3, 21.7, 28.7, 1724560664 +rocksdb, 27511, 27511, 0, 36, 11.7, 14.3, 18.3, 25.5, 34.4, 1724560675 +rocksdb, 29995, 29995, 0, 0, 11.4, 14.4, 20.3, 28.6, 37.5, 1724560685 +rocksdb, 32592, 32592, 0, 0, 11.7, 14.9, 21.2, 31.5, 46.4, 1724560696 +rocksdb, 35013, 35013, 0, 1, 5.2, 15.8, 25.0, 37.5, 58.1, 1724560707 +rocksdb, 37369, 37369, 0, 2, 5.1, 16.9, 30.3, 49.3, 76.1, 1724560717 +rocksdb, 40043, 40043, 0, 34, 10.7, 23.9, 56.2, 97.6, 153.6, 1724560728 +rocksdb, 42588, 42588, 0, 32, 13.6, 60.5, 152.8, 503.6, 915.0, 1724560739 +rocksdb, 44992, 44992, 0, 2, 23.4, 147.0, 6247.6, 7678.6, 3573737.8, 1724560749 diff --git a/paper_results/rocksdb/50-get-50-scan/skyloft_5us_utimer b/paper_results/rocksdb/50-get-50-scan/skyloft_5us_utimer new file mode 100644 index 0000000..296aedb --- /dev/null +++ b/paper_results/rocksdb/50-get-50-scan/skyloft_5us_utimer @@ -0,0 +1,17 @@ +rocksdb, 2481, 2481, 0, 4, 12.0, 14.8, 21.7, 31.6, 42.8, 1724561033 +rocksdb, 4962, 4962, 0, 2, 11.8, 14.5, 19.9, 29.0, 44.2, 1724561044 +rocksdb, 7509, 7509, 0, 10, 12.1, 14.4, 18.9, 26.8, 42.0, 1724561055 +rocksdb, 9972, 9972, 0, 11, 2.0, 14.3, 18.1, 24.5, 34.3, 1724561065 +rocksdb, 12464, 12464, 0, 0, 1.9, 14.2, 17.5, 22.0, 29.3, 1724561076 +rocksdb, 15039, 15039, 0, 1, 11.6, 14.2, 17.4, 21.4, 30.2, 1724561086 +rocksdb, 17614, 17614, 0, 2, 1.6, 14.0, 17.2, 20.9, 25.9, 1724561097 +rocksdb, 20097, 20097, 0, 0, 1.6, 14.0, 17.2, 21.1, 26.2, 1724561108 +rocksdb, 22392, 22392, 0, 1, 1.7, 14.0, 17.5, 22.9, 33.9, 1724561118 +rocksdb, 24985, 24985, 0, 43, 11.6, 14.2, 18.4, 27.2, 36.6, 1724561129 +rocksdb, 27534, 27534, 0, 0, 11.4, 14.4, 20.4, 27.7, 36.7, 1724561140 +rocksdb, 30015, 30015, 0, 0, 11.5, 15.1, 22.6, 32.9, 43.3, 1724561150 +rocksdb, 32653, 32653, 0, 3, 11.6, 16.4, 29.6, 50.2, 76.7, 1724561161 +rocksdb, 35168, 35168, 0, 0, 11.6, 18.6, 34.6, 55.7, 87.3, 1724561172 +rocksdb, 37387, 37387, 0, 3, 11.7, 27.1, 70.9, 135.0, 182.3, 1724561182 +rocksdb, 39947, 39947, 0, 3, 13.8, 82.9, 191.4, 4809.2, 1760687.8, 1724561193 +rocksdb, 42471, 42471, 0, 2, 32.2, 178.7, 6651.8, 7637.7, 4111513.0, 1724561204 diff --git a/paper_results/rocksdb/50-get-50-scan/skyloft_nopre b/paper_results/rocksdb/50-get-50-scan/skyloft_nopre new file mode 100644 index 0000000..47209d4 --- /dev/null +++ b/paper_results/rocksdb/50-get-50-scan/skyloft_nopre @@ -0,0 +1,19 @@ +rocksdb, 2483, 2483, 0, 6, 11.8, 13.9, 17.6, 26.0, 35.6, 1713370950 +rocksdb, 4978, 4978, 0, 1, 11.8, 13.8, 16.4, 19.9, 24.9, 1713370960 +rocksdb, 7550, 7550, 0, 2, 1.0, 13.7, 16.2, 18.2, 21.2, 1713370971 +rocksdb, 9966, 9966, 0, 4, 1.0, 13.7, 16.3, 18.7, 23.6, 1713370982 +rocksdb, 12437, 12437, 0, 4, 1.0, 13.6, 16.2, 18.1, 22.9, 1713370992 +rocksdb, 14924, 14924, 0, 5, 1.0, 13.6, 16.4, 18.5, 34.5, 1713371003 +rocksdb, 17484, 17484, 0, 0, 11.4, 13.5, 16.2, 18.3, 124.1, 1713371014 +rocksdb, 20082, 20082, 0, 3, 1.0, 13.4, 16.3, 38.7, 217.0, 1713371024 +rocksdb, 22444, 22444, 0, 50, 11.6, 13.4, 16.7, 92.1, 294.6, 1713371035 +rocksdb, 25046, 25046, 0, 0, 11.3, 13.3, 17.9, 166.8, 358.3, 1713371046 +rocksdb, 27390, 27390, 0, 9, 11.3, 13.4, 64.9, 256.4, 466.5, 1713371056 +rocksdb, 29881, 29881, 0, 6, 1.8, 13.4, 110.8, 312.0, 503.1, 1713371067 +rocksdb, 32376, 32376, 0, 3, 1.7, 13.6, 187.1, 441.1, 871.9, 1713371078 +rocksdb, 35017, 35017, 0, 4, 1.7, 16.8, 277.3, 578.4, 913.7, 1713371088 +rocksdb, 37496, 37496, 0, 6, 2.7, 55.7, 410.5, 889.4, 1512.5, 1713371099 +rocksdb, 40074, 40074, 0, 4, 2.6, 120.9, 591.6, 1169.7, 1971.2, 1713371110 +rocksdb, 42640, 42640, 0, 1, 11.4, 236.4, 989.5, 1819.7, 2685.6, 1713371120 +rocksdb, 44992, 44992, 0, 5, 11.4, 557.1, 1918.7, 3528.7, 4991.5, 1713371131 +rocksdb, 47337, 47337, 0, 4, 60.3, 15907.8, 40300.8, 48701.5, 51498.8, 1713371142 diff --git a/paper_results/schbench/linux_cfs_opt/112.txt b/paper_results/schbench/linux_cfs_opt/112.txt new file mode 100644 index 0000000..0926f29 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/112.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (95041 total samples) + 50.0th: 1422 (28523 samples) + 90.0th: 6872 (37998 samples) + * 99.0th: 15568 (8547 samples) + 99.9th: 56640 (857 samples) + min=1, max=73351 +Request Latencies percentiles (usec) runtime 10 (s) (94973 total samples) + 50.0th: 4824 (28847 samples) + 90.0th: 10736 (37587 samples) + * 99.0th: 23136 (8516 samples) + 99.9th: 61376 (858 samples) + min=2429, max=75107 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9424 (3 samples) + * 50.0th: 9456 (6 samples) + 90.0th: 9488 (1 samples) + min=9428, max=9586 +current rps: 9473 +Wakeup Latencies percentiles (usec) runtime 10 (s) (95079 total samples) + 50.0th: 1422 (28528 samples) + 90.0th: 6872 (38020 samples) + * 99.0th: 15568 (8557 samples) + 99.9th: 56640 (857 samples) + min=1, max=73351 +Request Latencies percentiles (usec) runtime 10 (s) (95087 total samples) + 50.0th: 4824 (28871 samples) + 90.0th: 10736 (37647 samples) + * 99.0th: 23136 (8521 samples) + 99.9th: 61376 (858 samples) + min=2429, max=75107 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9424 (3 samples) + * 50.0th: 9456 (6 samples) + 90.0th: 9488 (1 samples) + min=9428, max=9586 +average rps: 9509 +message_threads 1 +worker_threads 112 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/128.txt b/paper_results/schbench/linux_cfs_opt/128.txt new file mode 100644 index 0000000..822122a --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/128.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (94785 total samples) + 50.0th: 1698 (28436 samples) + 90.0th: 8336 (37924 samples) + * 99.0th: 18720 (8503 samples) + 99.9th: 58944 (848 samples) + min=1, max=77855 +Request Latencies percentiles (usec) runtime 10 (s) (94742 total samples) + 50.0th: 5816 (28415 samples) + 90.0th: 11856 (38134 samples) + * 99.0th: 26144 (8262 samples) + 99.9th: 64704 (853 samples) + min=2426, max=84940 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9424 (9 samples) + * 50.0th: 9424 (0 samples) + 90.0th: 9456 (1 samples) + min=9411, max=9638 +current rps: 9448 +Wakeup Latencies percentiles (usec) runtime 10 (s) (94857 total samples) + 50.0th: 1698 (28463 samples) + 90.0th: 8336 (37952 samples) + * 99.0th: 18720 (8509 samples) + 99.9th: 58944 (848 samples) + min=1, max=77855 +Request Latencies percentiles (usec) runtime 10 (s) (94872 total samples) + 50.0th: 5816 (28450 samples) + 90.0th: 11856 (38198 samples) + * 99.0th: 26080 (8268 samples) + 99.9th: 64704 (860 samples) + min=2426, max=84940 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9424 (9 samples) + * 50.0th: 9424 (0 samples) + 90.0th: 9456 (1 samples) + min=9411, max=9638 +average rps: 9487 +message_threads 1 +worker_threads 128 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/144.txt b/paper_results/schbench/linux_cfs_opt/144.txt new file mode 100644 index 0000000..342d926 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/144.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (94726 total samples) + 50.0th: 1906 (28410 samples) + 90.0th: 9584 (37898 samples) + * 99.0th: 18912 (8522 samples) + 99.9th: 59200 (848 samples) + min=1, max=75106 +Request Latencies percentiles (usec) runtime 10 (s) (94691 total samples) + 50.0th: 7048 (28756 samples) + 90.0th: 13680 (37445 samples) + * 99.0th: 26080 (8524 samples) + 99.9th: 64832 (852 samples) + min=2429, max=76534 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9392 (3 samples) + * 50.0th: 9424 (4 samples) + 90.0th: 9456 (3 samples) + min=9374, max=9602 +current rps: 9455 +Wakeup Latencies percentiles (usec) runtime 10 (s) (94831 total samples) + 50.0th: 1906 (28444 samples) + 90.0th: 9584 (37919 samples) + * 99.0th: 18912 (8540 samples) + 99.9th: 59200 (851 samples) + min=1, max=75106 +Request Latencies percentiles (usec) runtime 10 (s) (94841 total samples) + 50.0th: 7048 (28805 samples) + 90.0th: 13680 (37512 samples) + * 99.0th: 26080 (8536 samples) + 99.9th: 64832 (852 samples) + min=2429, max=76534 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9392 (3 samples) + * 50.0th: 9424 (4 samples) + 90.0th: 9456 (3 samples) + min=9374, max=9602 +average rps: 9484 +message_threads 1 +worker_threads 144 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/16.txt b/paper_results/schbench/linux_cfs_opt/16.txt new file mode 100644 index 0000000..9cbfe9e --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/16.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (63438 total samples) + 50.0th: 6 (23396 samples) + 90.0th: 9 (22892 samples) + * 99.0th: 10 (1771 samples) + 99.9th: 12 (289 samples) + min=1, max=32 +Request Latencies percentiles (usec) runtime 10 (s) (63835 total samples) + 50.0th: 2492 (29437 samples) + 90.0th: 2500 (7492 samples) + * 99.0th: 2540 (2058 samples) + 99.9th: 3372 (519 samples) + min=2428, max=4064 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 6376 (4 samples) + * 50.0th: 6392 (7 samples) + 90.0th: 6392 (0 samples) + min=6364, max=6394 +current rps: 6384 +Wakeup Latencies percentiles (usec) runtime 10 (s) (63439 total samples) + 50.0th: 6 (23397 samples) + 90.0th: 9 (22892 samples) + * 99.0th: 10 (1771 samples) + 99.9th: 12 (289 samples) + min=1, max=32 +Request Latencies percentiles (usec) runtime 10 (s) (63852 total samples) + 50.0th: 2492 (29445 samples) + 90.0th: 2500 (7494 samples) + * 99.0th: 2540 (2063 samples) + 99.9th: 3372 (519 samples) + min=2428, max=4064 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 6376 (4 samples) + * 50.0th: 6392 (7 samples) + 90.0th: 6392 (0 samples) + min=6364, max=6394 +average rps: 6385 +message_threads 1 +worker_threads 16 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/160.txt b/paper_results/schbench/linux_cfs_opt/160.txt new file mode 100644 index 0000000..201b52b --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/160.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (94786 total samples) + 50.0th: 2244 (28470 samples) + 90.0th: 11280 (37874 samples) + * 99.0th: 24160 (8502 samples) + 99.9th: 63552 (851 samples) + min=1, max=87639 +Request Latencies percentiles (usec) runtime 10 (s) (94708 total samples) + 50.0th: 7096 (29524 samples) + 90.0th: 14320 (36093 samples) + * 99.0th: 30688 (8502 samples) + 99.9th: 66944 (847 samples) + min=2428, max=89979 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9392 (4 samples) + * 50.0th: 9424 (3 samples) + 90.0th: 9456 (3 samples) + min=9388, max=9637 +current rps: 9418 +Wakeup Latencies percentiles (usec) runtime 10 (s) (94863 total samples) + 50.0th: 2244 (28474 samples) + 90.0th: 11280 (37915 samples) + * 99.0th: 24160 (8527 samples) + 99.9th: 63552 (851 samples) + min=1, max=87639 +Request Latencies percentiles (usec) runtime 10 (s) (94873 total samples) + 50.0th: 7096 (29557 samples) + 90.0th: 14320 (36166 samples) + * 99.0th: 30688 (8528 samples) + 99.9th: 66944 (847 samples) + min=2428, max=89979 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9392 (4 samples) + * 50.0th: 9424 (3 samples) + 90.0th: 9456 (3 samples) + min=9388, max=9637 +average rps: 9487 +message_threads 1 +worker_threads 160 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/176.txt b/paper_results/schbench/linux_cfs_opt/176.txt new file mode 100644 index 0000000..b5eedb7 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/176.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (95505 total samples) + 50.0th: 2380 (28741 samples) + 90.0th: 12400 (38144 samples) + * 99.0th: 24416 (8554 samples) + 99.9th: 63936 (859 samples) + min=1, max=85956 +Request Latencies percentiles (usec) runtime 10 (s) (95418 total samples) + 50.0th: 7112 (26398 samples) + 90.0th: 16416 (37917 samples) + * 99.0th: 33344 (8571 samples) + 99.9th: 69248 (862 samples) + min=2423, max=88158 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9488 (7 samples) + * 50.0th: 9488 (0 samples) + 90.0th: 9520 (3 samples) + min=9476, max=9658 +current rps: 9476 +Wakeup Latencies percentiles (usec) runtime 10 (s) (95594 total samples) + 50.0th: 2380 (28713 samples) + 90.0th: 12400 (38194 samples) + * 99.0th: 24480 (8580 samples) + 99.9th: 63936 (859 samples) + min=1, max=85956 +Request Latencies percentiles (usec) runtime 10 (s) (95605 total samples) + 50.0th: 7112 (26438 samples) + 90.0th: 16416 (37996 samples) + * 99.0th: 33344 (8593 samples) + 99.9th: 69248 (862 samples) + min=2423, max=88158 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9488 (7 samples) + * 50.0th: 9488 (0 samples) + 90.0th: 9520 (3 samples) + min=9476, max=9658 +average rps: 9561 +message_threads 1 +worker_threads 176 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/192.txt b/paper_results/schbench/linux_cfs_opt/192.txt new file mode 100644 index 0000000..5335499 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/192.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (95451 total samples) + 50.0th: 2716 (28636 samples) + 90.0th: 14160 (38200 samples) + * 99.0th: 30304 (8571 samples) + 99.9th: 70528 (860 samples) + min=1, max=87717 +Request Latencies percentiles (usec) runtime 10 (s) (95373 total samples) + 50.0th: 7816 (26569 samples) + 90.0th: 17760 (38174 samples) + * 99.0th: 35392 (8563 samples) + 99.9th: 73600 (850 samples) + min=2426, max=88324 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9456 (3 samples) + * 50.0th: 9488 (7 samples) + 90.0th: 9488 (0 samples) + min=9451, max=9672 +current rps: 9501 +Wakeup Latencies percentiles (usec) runtime 10 (s) (95570 total samples) + 50.0th: 2732 (28690 samples) + 90.0th: 14160 (38202 samples) + * 99.0th: 30304 (8599 samples) + 99.9th: 70528 (860 samples) + min=1, max=87717 +Request Latencies percentiles (usec) runtime 10 (s) (95573 total samples) + 50.0th: 7832 (26657 samples) + 90.0th: 17760 (38227 samples) + * 99.0th: 35392 (8581 samples) + 99.9th: 73600 (850 samples) + min=2426, max=88324 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9456 (3 samples) + * 50.0th: 9488 (7 samples) + 90.0th: 9488 (0 samples) + min=9451, max=9672 +average rps: 9557 +message_threads 1 +worker_threads 192 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/208.txt b/paper_results/schbench/linux_cfs_opt/208.txt new file mode 100644 index 0000000..b0ebd64 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/208.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (95655 total samples) + 50.0th: 3348 (28680 samples) + 90.0th: 15312 (38313 samples) + * 99.0th: 29024 (8560 samples) + 99.9th: 66688 (860 samples) + min=1, max=90691 +Request Latencies percentiles (usec) runtime 10 (s) (95578 total samples) + 50.0th: 9360 (28688 samples) + 90.0th: 18848 (37959 samples) + * 99.0th: 39616 (8364 samples) + 99.9th: 72320 (862 samples) + min=2428, max=91970 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9488 (5 samples) + * 50.0th: 9520 (5 samples) + 90.0th: 9520 (0 samples) + min=9483, max=9680 +current rps: 9489 +Wakeup Latencies percentiles (usec) runtime 10 (s) (95791 total samples) + 50.0th: 3348 (28708 samples) + 90.0th: 15312 (38363 samples) + * 99.0th: 28960 (8570 samples) + 99.9th: 66688 (867 samples) + min=1, max=90691 +Request Latencies percentiles (usec) runtime 10 (s) (95798 total samples) + 50.0th: 9360 (28781 samples) + 90.0th: 18848 (38009 samples) + * 99.0th: 39488 (8387 samples) + 99.9th: 72320 (864 samples) + min=2428, max=91970 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9488 (5 samples) + * 50.0th: 9520 (5 samples) + 90.0th: 9520 (0 samples) + min=9483, max=9680 +average rps: 9580 +message_threads 1 +worker_threads 208 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/224.txt b/paper_results/schbench/linux_cfs_opt/224.txt new file mode 100644 index 0000000..072b2be --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/224.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (96616 total samples) + 50.0th: 3852 (28972 samples) + 90.0th: 16672 (38696 samples) + * 99.0th: 33344 (8643 samples) + 99.9th: 74112 (863 samples) + min=1, max=89993 +Request Latencies percentiles (usec) runtime 10 (s) (96500 total samples) + 50.0th: 9424 (29916 samples) + 90.0th: 20768 (36374 samples) + * 99.0th: 47296 (8671 samples) + 99.9th: 77184 (867 samples) + min=2435, max=98967 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9520 (6 samples) + * 50.0th: 9520 (0 samples) + 90.0th: 9552 (4 samples) + min=9513, max=9725 +current rps: 9526 +Wakeup Latencies percentiles (usec) runtime 10 (s) (96729 total samples) + 50.0th: 3860 (29009 samples) + 90.0th: 16672 (38737 samples) + * 99.0th: 33344 (8658 samples) + 99.9th: 74112 (863 samples) + min=1, max=89993 +Request Latencies percentiles (usec) runtime 10 (s) (96734 total samples) + 50.0th: 9424 (29981 samples) + 90.0th: 20768 (36489 samples) + * 99.0th: 47040 (8671 samples) + 99.9th: 77184 (871 samples) + min=2435, max=98967 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9520 (6 samples) + * 50.0th: 9520 (0 samples) + 90.0th: 9552 (4 samples) + min=9513, max=9725 +average rps: 9673 +message_threads 1 +worker_threads 224 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/24.txt b/paper_results/schbench/linux_cfs_opt/24.txt new file mode 100644 index 0000000..d0ebbf8 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/24.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (93427 total samples) + 50.0th: 6 (31637 samples) + 90.0th: 10 (26863 samples) + * 99.0th: 20 (6871 samples) + 99.9th: 571 (822 samples) + min=1, max=1010 +Request Latencies percentiles (usec) runtime 10 (s) (94676 total samples) + 50.0th: 2492 (32318 samples) + 90.0th: 2508 (34996 samples) + * 99.0th: 2852 (5406 samples) + 99.9th: 3668 (841 samples) + min=2427, max=4952 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9456 (7 samples) + * 50.0th: 9456 (0 samples) + 90.0th: 9488 (4 samples) + min=9439, max=9496 +current rps: 9446 +Wakeup Latencies percentiles (usec) runtime 10 (s) (93427 total samples) + 50.0th: 6 (31637 samples) + 90.0th: 10 (26863 samples) + * 99.0th: 20 (6871 samples) + 99.9th: 571 (822 samples) + min=1, max=1010 +Request Latencies percentiles (usec) runtime 10 (s) (94700 total samples) + 50.0th: 2492 (32324 samples) + 90.0th: 2508 (35007 samples) + * 99.0th: 2852 (5412 samples) + 99.9th: 3668 (842 samples) + min=2427, max=4952 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9456 (7 samples) + * 50.0th: 9456 (0 samples) + 90.0th: 9488 (4 samples) + min=9439, max=9496 +average rps: 9470 +message_threads 1 +worker_threads 24 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/240.txt b/paper_results/schbench/linux_cfs_opt/240.txt new file mode 100644 index 0000000..236b275 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/240.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (96687 total samples) + 50.0th: 4440 (29024 samples) + 90.0th: 17824 (38708 samples) + * 99.0th: 39744 (8638 samples) + 99.9th: 74624 (872 samples) + min=1, max=92148 +Request Latencies percentiles (usec) runtime 10 (s) (96586 total samples) + 50.0th: 9456 (28827 samples) + 90.0th: 21280 (38373 samples) + * 99.0th: 58944 (8631 samples) + 99.9th: 78976 (834 samples) + min=2428, max=94169 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9520 (7 samples) + * 50.0th: 9520 (0 samples) + 90.0th: 9584 (3 samples) + min=9070, max=9733 +current rps: 9508 +Wakeup Latencies percentiles (usec) runtime 10 (s) (96826 total samples) + 50.0th: 4456 (29053 samples) + 90.0th: 17824 (38717 samples) + * 99.0th: 39744 (8676 samples) + 99.9th: 74624 (872 samples) + min=1, max=92148 +Request Latencies percentiles (usec) runtime 10 (s) (96834 total samples) + 50.0th: 9456 (28889 samples) + 90.0th: 21280 (38488 samples) + * 99.0th: 58816 (8619 samples) + 99.9th: 78976 (873 samples) + min=2428, max=94169 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9520 (7 samples) + * 50.0th: 9520 (0 samples) + 90.0th: 9584 (3 samples) + min=9070, max=9733 +average rps: 9683 +message_threads 1 +worker_threads 240 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/256.txt b/paper_results/schbench/linux_cfs_opt/256.txt new file mode 100644 index 0000000..6267bff --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/256.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (95947 total samples) + 50.0th: 4712 (28777 samples) + 90.0th: 18592 (38453 samples) + * 99.0th: 33984 (8546 samples) + 99.9th: 75136 (858 samples) + min=1, max=85580 +Request Latencies percentiles (usec) runtime 10 (s) (95903 total samples) + 50.0th: 10096 (28650 samples) + 90.0th: 22944 (38358 samples) + * 99.0th: 54592 (8613 samples) + 99.9th: 79488 (864 samples) + min=2430, max=96043 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9520 (3 samples) + * 50.0th: 9552 (6 samples) + 90.0th: 9584 (1 samples) + min=9522, max=9702 +current rps: 9562 +Wakeup Latencies percentiles (usec) runtime 10 (s) (96166 total samples) + 50.0th: 4696 (28874 samples) + 90.0th: 18592 (38540 samples) + * 99.0th: 33856 (8540 samples) + 99.9th: 74880 (864 samples) + min=1, max=85580 +Request Latencies percentiles (usec) runtime 10 (s) (96171 total samples) + 50.0th: 10096 (28730 samples) + 90.0th: 22944 (38502 samples) + * 99.0th: 54336 (8620 samples) + 99.9th: 79232 (865 samples) + min=2430, max=96043 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9520 (3 samples) + * 50.0th: 9552 (6 samples) + 90.0th: 9584 (1 samples) + min=9522, max=9702 +average rps: 9617 +message_threads 1 +worker_threads 256 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/32.txt b/paper_results/schbench/linux_cfs_opt/32.txt new file mode 100644 index 0000000..6d5eb6b --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/32.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (94733 total samples) + 50.0th: 9 (29141 samples) + 90.0th: 417 (36940 samples) + * 99.0th: 1001 (8887 samples) + 99.9th: 1126 (487 samples) + min=1, max=1836 +Request Latencies percentiles (usec) runtime 10 (s) (95049 total samples) + 50.0th: 2812 (22897 samples) + 90.0th: 4424 (38024 samples) + * 99.0th: 5224 (8434 samples) + 99.9th: 6056 (824 samples) + min=2429, max=7736 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9488 (7 samples) + * 50.0th: 9488 (0 samples) + 90.0th: 9520 (4 samples) + min=9479, max=9534 +current rps: 9517 +Wakeup Latencies percentiles (usec) runtime 10 (s) (94739 total samples) + 50.0th: 9 (29141 samples) + 90.0th: 417 (36944 samples) + * 99.0th: 1001 (8889 samples) + 99.9th: 1126 (487 samples) + min=1, max=1836 +Request Latencies percentiles (usec) runtime 10 (s) (95083 total samples) + 50.0th: 2812 (22910 samples) + 90.0th: 4424 (38036 samples) + * 99.0th: 5224 (8440 samples) + 99.9th: 6056 (824 samples) + min=2429, max=7736 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9488 (7 samples) + * 50.0th: 9488 (0 samples) + 90.0th: 9520 (4 samples) + min=9479, max=9534 +average rps: 9508 +message_threads 1 +worker_threads 32 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/4.txt b/paper_results/schbench/linux_cfs_opt/4.txt new file mode 100644 index 0000000..ef107be --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/4.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (15956 total samples) + 50.0th: 6 (0 samples) + 90.0th: 7 (2882 samples) + * 99.0th: 8 (440 samples) + 99.9th: 10 (125 samples) + min=1, max=16 +Request Latencies percentiles (usec) runtime 10 (s) (15970 total samples) + 50.0th: 2492 (6909 samples) + 90.0th: 2492 (0 samples) + * 99.0th: 2532 (1274 samples) + 99.9th: 3316 (127 samples) + min=2427, max=4056 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 1594 (3 samples) + * 50.0th: 1598 (8 samples) + 90.0th: 1598 (0 samples) + min=1593, max=1599 +current rps: 1599 +Wakeup Latencies percentiles (usec) runtime 10 (s) (15956 total samples) + 50.0th: 6 (0 samples) + 90.0th: 7 (2882 samples) + * 99.0th: 8 (440 samples) + 99.9th: 10 (125 samples) + min=1, max=16 +Request Latencies percentiles (usec) runtime 10 (s) (15974 total samples) + 50.0th: 2492 (6911 samples) + 90.0th: 2492 (0 samples) + * 99.0th: 2532 (1274 samples) + 99.9th: 3316 (127 samples) + min=2427, max=4056 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 1594 (3 samples) + * 50.0th: 1598 (8 samples) + 90.0th: 1598 (0 samples) + min=1593, max=1599 +average rps: 1597 +message_threads 1 +worker_threads 4 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/40.txt b/paper_results/schbench/linux_cfs_opt/40.txt new file mode 100644 index 0000000..80cc5f2 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/40.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (96779 total samples) + 50.0th: 22 (26330 samples) + 90.0th: 999 (40314 samples) + * 99.0th: 1017 (6666 samples) + 99.9th: 1330 (854 samples) + min=1, max=1764 +Request Latencies percentiles (usec) runtime 10 (s) (96947 total samples) + 50.0th: 3588 (29029 samples) + 90.0th: 4840 (40074 samples) + * 99.0th: 5688 (7319 samples) + 99.9th: 6792 (868 samples) + min=2430, max=9229 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9680 (4 samples) + * 50.0th: 9712 (7 samples) + 90.0th: 9712 (0 samples) + min=9584, max=9724 +current rps: 9716 +Wakeup Latencies percentiles (usec) runtime 10 (s) (96783 total samples) + 50.0th: 22 (26332 samples) + 90.0th: 999 (40316 samples) + * 99.0th: 1017 (6666 samples) + 99.9th: 1330 (854 samples) + min=1, max=1764 +Request Latencies percentiles (usec) runtime 10 (s) (96990 total samples) + 50.0th: 3588 (29042 samples) + 90.0th: 4840 (40096 samples) + * 99.0th: 5688 (7323 samples) + 99.9th: 6792 (868 samples) + min=2430, max=9229 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9680 (4 samples) + * 50.0th: 9712 (7 samples) + 90.0th: 9712 (0 samples) + min=9584, max=9724 +average rps: 9699 +message_threads 1 +worker_threads 40 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/48.txt b/paper_results/schbench/linux_cfs_opt/48.txt new file mode 100644 index 0000000..2fee266 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/48.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (99415 total samples) + 50.0th: 196 (28759 samples) + 90.0th: 1001 (42620 samples) + * 99.0th: 1318 (6121 samples) + 99.9th: 1682 (849 samples) + min=1, max=2343 +Request Latencies percentiles (usec) runtime 10 (s) (99547 total samples) + 50.0th: 4408 (30071 samples) + 90.0th: 5208 (39710 samples) + * 99.0th: 6328 (8845 samples) + 99.9th: 7496 (890 samples) + min=2436, max=9137 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9936 (6 samples) + * 50.0th: 9936 (0 samples) + 90.0th: 9968 (5 samples) + min=9918, max=9971 +current rps: 9949 +Wakeup Latencies percentiles (usec) runtime 10 (s) (99425 total samples) + 50.0th: 196 (28759 samples) + 90.0th: 1001 (42625 samples) + * 99.0th: 1318 (6126 samples) + 99.9th: 1682 (849 samples) + min=1, max=2343 +Request Latencies percentiles (usec) runtime 10 (s) (99599 total samples) + 50.0th: 4408 (30096 samples) + 90.0th: 5208 (39718 samples) + * 99.0th: 6328 (8850 samples) + 99.9th: 7496 (891 samples) + min=2436, max=9137 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 9936 (6 samples) + * 50.0th: 9936 (0 samples) + 90.0th: 9968 (5 samples) + min=9918, max=9971 +average rps: 9960 +message_threads 1 +worker_threads 48 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/56.txt b/paper_results/schbench/linux_cfs_opt/56.txt new file mode 100644 index 0000000..94c0a73 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/56.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (100093 total samples) + 50.0th: 659 (30007 samples) + 90.0th: 1003 (41151 samples) + * 99.0th: 2002 (8204 samples) + 99.9th: 2300 (467 samples) + min=1, max=3008 +Request Latencies percentiles (usec) runtime 10 (s) (100137 total samples) + 50.0th: 4488 (31481 samples) + 90.0th: 6344 (38819 samples) + * 99.0th: 7736 (8786 samples) + 99.9th: 9232 (905 samples) + min=2433, max=11487 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10000 (7 samples) + * 50.0th: 10000 (0 samples) + 90.0th: 10032 (3 samples) + min=9978, max=10056 +current rps: 10028 +Wakeup Latencies percentiles (usec) runtime 10 (s) (100122 total samples) + 50.0th: 659 (30165 samples) + 90.0th: 1003 (41160 samples) + * 99.0th: 2002 (8210 samples) + 99.9th: 2292 (462 samples) + min=1, max=3008 +Request Latencies percentiles (usec) runtime 10 (s) (100211 total samples) + 50.0th: 4488 (31506 samples) + 90.0th: 6344 (38854 samples) + * 99.0th: 7736 (8787 samples) + 99.9th: 9232 (905 samples) + min=2433, max=11487 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10000 (7 samples) + * 50.0th: 10000 (0 samples) + 90.0th: 10032 (3 samples) + min=9978, max=10056 +average rps: 10021 +message_threads 1 +worker_threads 56 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/64.txt b/paper_results/schbench/linux_cfs_opt/64.txt new file mode 100644 index 0000000..d03a603 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/64.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (100557 total samples) + 50.0th: 775 (30126 samples) + 90.0th: 1138 (40195 samples) + * 99.0th: 2006 (9147 samples) + 99.9th: 2452 (796 samples) + min=1, max=3472 +Request Latencies percentiles (usec) runtime 10 (s) (100586 total samples) + 50.0th: 5336 (30435 samples) + 90.0th: 7080 (40148 samples) + * 99.0th: 8368 (8862 samples) + 99.9th: 10192 (901 samples) + min=2433, max=12592 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10032 (3 samples) + * 50.0th: 10064 (7 samples) + 90.0th: 10064 (0 samples) + min=9993, max=10095 +current rps: 10049 +Wakeup Latencies percentiles (usec) runtime 10 (s) (100572 total samples) + 50.0th: 775 (30129 samples) + 90.0th: 1138 (40200 samples) + * 99.0th: 2006 (9149 samples) + 99.9th: 2452 (796 samples) + min=1, max=3472 +Request Latencies percentiles (usec) runtime 10 (s) (100655 total samples) + 50.0th: 5336 (30459 samples) + 90.0th: 7080 (40180 samples) + * 99.0th: 8368 (8863 samples) + 99.9th: 10192 (901 samples) + min=2433, max=12592 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10032 (3 samples) + * 50.0th: 10064 (7 samples) + 90.0th: 10064 (0 samples) + min=9993, max=10095 +average rps: 10066 +message_threads 1 +worker_threads 64 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/72.txt b/paper_results/schbench/linux_cfs_opt/72.txt new file mode 100644 index 0000000..026a4ec --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/72.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (100699 total samples) + 50.0th: 843 (29992 samples) + 90.0th: 1490 (40263 samples) + * 99.0th: 2132 (9082 samples) + 99.9th: 3004 (943 samples) + min=1, max=4160 +Request Latencies percentiles (usec) runtime 10 (s) (100721 total samples) + 50.0th: 6136 (30340 samples) + 90.0th: 7544 (40193 samples) + * 99.0th: 9584 (9044 samples) + 99.9th: 11312 (885 samples) + min=2452, max=13752 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10032 (3 samples) + * 50.0th: 10064 (5 samples) + 90.0th: 10096 (3 samples) + min=10010, max=10106 +current rps: 10063 +Wakeup Latencies percentiles (usec) runtime 10 (s) (100723 total samples) + 50.0th: 843 (30000 samples) + 90.0th: 1490 (40271 samples) + * 99.0th: 2132 (9088 samples) + 99.9th: 3004 (943 samples) + min=1, max=4160 +Request Latencies percentiles (usec) runtime 10 (s) (100804 total samples) + 50.0th: 6136 (30361 samples) + 90.0th: 7544 (40219 samples) + * 99.0th: 9552 (9022 samples) + 99.9th: 11312 (912 samples) + min=2452, max=13752 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10032 (3 samples) + * 50.0th: 10064 (5 samples) + 90.0th: 10096 (3 samples) + min=10010, max=10106 +average rps: 10080 +message_threads 1 +worker_threads 72 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/8.txt b/paper_results/schbench/linux_cfs_opt/8.txt new file mode 100644 index 0000000..36935a0 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/8.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (31874 total samples) + 50.0th: 6 (15794 samples) + 90.0th: 8 (6780 samples) + * 99.0th: 10 (1618 samples) + 99.9th: 10 (0 samples) + min=1, max=89 +Request Latencies percentiles (usec) runtime 10 (s) (31937 total samples) + 50.0th: 2492 (14415 samples) + 90.0th: 2492 (0 samples) + * 99.0th: 2532 (2461 samples) + 99.9th: 3324 (285 samples) + min=2425, max=4008 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 3188 (3 samples) + * 50.0th: 3196 (8 samples) + 90.0th: 3196 (0 samples) + min=3187, max=3199 +current rps: 3194 +Wakeup Latencies percentiles (usec) runtime 10 (s) (31875 total samples) + 50.0th: 6 (15795 samples) + 90.0th: 8 (6780 samples) + * 99.0th: 10 (1618 samples) + 99.9th: 10 (0 samples) + min=1, max=89 +Request Latencies percentiles (usec) runtime 10 (s) (31946 total samples) + 50.0th: 2492 (14420 samples) + 90.0th: 2492 (0 samples) + * 99.0th: 2532 (2463 samples) + 99.9th: 3324 (285 samples) + min=2425, max=4008 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 3188 (3 samples) + * 50.0th: 3196 (8 samples) + 90.0th: 3196 (0 samples) + min=3187, max=3199 +average rps: 3195 +message_threads 1 +worker_threads 8 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/80.txt b/paper_results/schbench/linux_cfs_opt/80.txt new file mode 100644 index 0000000..5dea1bd --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/80.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (100751 total samples) + 50.0th: 843 (29985 samples) + 90.0th: 1998 (42028 samples) + * 99.0th: 3004 (8046 samples) + 99.9th: 3236 (189 samples) + min=1, max=5182 +Request Latencies percentiles (usec) runtime 10 (s) (100759 total samples) + 50.0th: 6568 (29113 samples) + 90.0th: 9072 (40352 samples) + * 99.0th: 10704 (8834 samples) + 99.9th: 13104 (901 samples) + min=2485, max=16591 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10032 (3 samples) + * 50.0th: 10064 (5 samples) + 90.0th: 10096 (3 samples) + min=10026, max=10108 +current rps: 10042 +Wakeup Latencies percentiles (usec) runtime 10 (s) (100796 total samples) + 50.0th: 843 (29994 samples) + 90.0th: 1998 (42045 samples) + * 99.0th: 3004 (8056 samples) + 99.9th: 3236 (189 samples) + min=1, max=5182 +Request Latencies percentiles (usec) runtime 10 (s) (100870 total samples) + 50.0th: 6568 (29145 samples) + 90.0th: 9072 (40380 samples) + * 99.0th: 10704 (8845 samples) + 99.9th: 13104 (903 samples) + min=2485, max=16591 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10032 (3 samples) + * 50.0th: 10064 (5 samples) + 90.0th: 10096 (3 samples) + min=10026, max=10108 +average rps: 10087 +message_threads 1 +worker_threads 80 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/88.txt b/paper_results/schbench/linux_cfs_opt/88.txt new file mode 100644 index 0000000..a243346 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/88.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (100820 total samples) + 50.0th: 847 (29993 samples) + 90.0th: 2002 (43616 samples) + * 99.0th: 3004 (6231 samples) + 99.9th: 3388 (445 samples) + min=1, max=6002 +Request Latencies percentiles (usec) runtime 10 (s) (100835 total samples) + 50.0th: 7544 (30396 samples) + 90.0th: 9488 (40664 samples) + * 99.0th: 11632 (8584 samples) + 99.9th: 14192 (889 samples) + min=2451, max=17739 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10064 (6 samples) + * 50.0th: 10064 (0 samples) + 90.0th: 10128 (5 samples) + min=9967, max=10117 +current rps: 10117 +Wakeup Latencies percentiles (usec) runtime 10 (s) (100835 total samples) + 50.0th: 847 (29996 samples) + 90.0th: 2002 (43623 samples) + * 99.0th: 3004 (6234 samples) + 99.9th: 3388 (445 samples) + min=1, max=6002 +Request Latencies percentiles (usec) runtime 10 (s) (100930 total samples) + 50.0th: 7544 (30426 samples) + 90.0th: 9488 (40693 samples) + * 99.0th: 11632 (8588 samples) + 99.9th: 14192 (889 samples) + min=2451, max=17739 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10064 (6 samples) + * 50.0th: 10064 (0 samples) + 90.0th: 10128 (5 samples) + min=9967, max=10117 +average rps: 10093 +message_threads 1 +worker_threads 88 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/96.txt b/paper_results/schbench/linux_cfs_opt/96.txt new file mode 100644 index 0000000..fa6d720 --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/96.txt @@ -0,0 +1,40 @@ +Wakeup Latencies percentiles (usec) runtime 10 (s) (101013 total samples) + 50.0th: 827 (30303 samples) + 90.0th: 2002 (41364 samples) + * 99.0th: 3012 (8113 samples) + 99.9th: 4004 (958 samples) + min=1, max=5038 +Request Latencies percentiles (usec) runtime 10 (s) (101031 total samples) + 50.0th: 8336 (31356 samples) + 90.0th: 9904 (39238 samples) + * 99.0th: 12560 (9068 samples) + 99.9th: 15120 (902 samples) + min=2490, max=19115 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10064 (3 samples) + * 50.0th: 10096 (4 samples) + 90.0th: 10128 (4 samples) + min=10029, max=10123 +current rps: 10104 +Wakeup Latencies percentiles (usec) runtime 10 (s) (101033 total samples) + 50.0th: 827 (30306 samples) + 90.0th: 2002 (41372 samples) + * 99.0th: 3012 (8115 samples) + 99.9th: 4004 (958 samples) + min=1, max=5038 +Request Latencies percentiles (usec) runtime 10 (s) (101132 total samples) + 50.0th: 8336 (31376 samples) + 90.0th: 9904 (39266 samples) + * 99.0th: 12560 (9071 samples) + 99.9th: 15120 (902 samples) + min=2490, max=19115 +RPS percentiles (requests) runtime 10 (s) (11 total samples) + 20.0th: 10064 (3 samples) + * 50.0th: 10096 (4 samples) + 90.0th: 10128 (4 samples) + min=10029, max=10123 +average rps: 10113 +message_threads 1 +worker_threads 96 +operations 10 +matrix_size 73 diff --git a/paper_results/schbench/linux_cfs_opt/all.csv b/paper_results/schbench/linux_cfs_opt/all.csv new file mode 100644 index 0000000..0e7eabe --- /dev/null +++ b/paper_results/schbench/linux_cfs_opt/all.csv @@ -0,0 +1,14 @@ +cores,lat99,rps50 +4,8,1598,2532 +8,10,3196,2532 +16,10,6392,2540 +24,20,9456,2852 +32,1001,9488,5224 +40,1017,9712,5688 +48,1318,9936,6328 +56,2002,10000,7736 +64,2006,10064,8368 +72,2132,10064,9552 +80,3004,10064,10704 +88,3004,10064,11632 +96,3012,10096,12560 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index b998a06..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -absl-py diff --git a/scripts/build.sh b/scripts/build.sh index c4e75db..ad840ee 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -8,22 +8,25 @@ preempt_quantum=$3 if [[ $app_name =~ synthetic-(.*) ]]; then params_file=$script_dir/params/shinjuku.params - build_cmd="make build SCHED=${BASH_REMATCH[1]} UINTR=1 DPDK=0 STAT=0" + build_cmd="make install SCHED=${BASH_REMATCH[1]} UINTR=1 DPDK=0" elif [[ $app_name =~ schbench-([a-zA-Z0-9]+).* ]]; then params_file=$script_dir/params/$app_name.params - build_cmd="make schbench SCHED=${BASH_REMATCH[1]} UINTR=1 DPDK=0 STAT=0" + build_cmd="make schbench SCHED=${BASH_REMATCH[1]} UINTR=1 DPDK=0" elif [ $app_name == "memcached" ]; then params_file=$script_dir/params/$app_name.params - build_cmd="make memcached SCHED=fifo UINTR=0 DPDK=1 STAT=0" + build_cmd="make memcached SCHED=fifo UINTR=0 DPDK=1" elif [[ $app_name =~ rocksdb-server-([a-zA-Z0-9]+) ]]; then params_file=$script_dir/params/$app_name.params - build_cmd="make rocksdb SCHED=fifo UINTR=1 DPDK=1 STAT=0" + build_cmd="make rocksdb SCHED=fifo UINTR=1 DPDK=1 FXSAVE=1" +elif [[ $app_name =~ rocksdb-server-([a-zA-Z0-9]+)-utimer ]]; then + params_file=$script_dir/params/$app_name.params + build_cmd="make rocksdb SCHED=fifo UINTR=1 DPDK=1 FXSAVE=1" elif [ $app_name == "rocksdb-server" ]; then params_file=$script_dir/params/$app_name.params - build_cmd="make rocksdb SCHED=fifo UINTR=0 DPDK=1 STAT=0" -elif [ $app_name == "bench_thread" ]; then - params_file=$script_dir/params/thread.params - build_cmd="make build SCHED=rr UINTR=0 DPDK=0 STAT=0" + build_cmd="make rocksdb SCHED=fifo UINTR=0 DPDK=1" +elif [ $app_name == "microbench" ]; then + params_file=$script_dir/params/microbench.params + build_cmd="make microbench SCHED=rr UINTR=0 DPDK=0" fi # Generate parameters diff --git a/scripts/debug.sh b/scripts/debug.sh new file mode 100755 index 0000000..ed5b236 --- /dev/null +++ b/scripts/debug.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +APP=hello + +BIN_DIR=$(dirname "$0")/../build/bin + +if [ ! -z "$1" ]; then + APP=$1 + shift 1; +fi + +sudo rm -rf /dev/shm/skyloft_* /mnt/huge/skyloft_* +sudo ipcrm -a > /dev/null 2>&1 + +sudo gdb --args ${BIN_DIR}/$APP $@ diff --git a/scripts/params/memcached.params b/scripts/params/memcached.params index 826aafa..989c430 100644 --- a/scripts/params/memcached.params +++ b/scripts/params/memcached.params @@ -1,4 +1,3 @@ #define USED_CPUS 5 #define IO_CPU 4 #define USED_HW_CPU_LIST "1,2,3,4,22" -#define MAX_APPS 1 \ No newline at end of file diff --git a/scripts/params/thread.params b/scripts/params/microbench.params similarity index 100% rename from scripts/params/thread.params rename to scripts/params/microbench.params diff --git a/scripts/params/rocksdb-server-20us.params b/scripts/params/rocksdb-server-20us.params index 22d2beb..3f14925 100644 --- a/scripts/params/rocksdb-server-20us.params +++ b/scripts/params/rocksdb-server-20us.params @@ -1,4 +1,4 @@ -#define USED_CPUS 15 -#define IO_CPU 14 -#define USED_HW_CPU_LIST "1,2,3,4,5,6,7,8,9,10,11,12,13,14,22" -#define TIMER_HZ 50000 +#define USED_CPUS 15 +#define IO_CPU 14 +#define USED_HW_CPU_LIST "1,2,3,4,5,6,7,8,9,10,11,12,13,14,22" +#define TIMER_HZ 50000 diff --git a/scripts/params/rocksdb-server-5us-utimer.params b/scripts/params/rocksdb-server-5us-utimer.params new file mode 100644 index 0000000..cfb7356 --- /dev/null +++ b/scripts/params/rocksdb-server-5us-utimer.params @@ -0,0 +1,7 @@ +#define USED_CPUS 15 +#define IO_CPU 14 +#define USED_HW_CPU_LIST "1,2,3,4,5,6,7,8,9,10,11,12,13,14,22" + +#define UTIMER 1 +#define UTIMER_CPU 13 +#define TIMER_HZ 200000 diff --git a/scripts/params/schbench-cfs-50us.params b/scripts/params/schbench-cfs-50us.params index 326e4bd..9cb1450 100644 --- a/scripts/params/schbench-cfs-50us.params +++ b/scripts/params/schbench-cfs-50us.params @@ -1,3 +1,3 @@ -#define USED_CPUS 22 -#define USED_HW_CPU_LIST "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21" +#define USED_CPUS 24 +#define USED_HW_CPU_LIST "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23" #define TIMER_HZ 100000 diff --git a/scripts/params/schbench-rr-50us.params b/scripts/params/schbench-rr-50us.params index 231e709..0143c27 100644 --- a/scripts/params/schbench-rr-50us.params +++ b/scripts/params/schbench-rr-50us.params @@ -1,4 +1,4 @@ -#define USED_CPUS 22 -#define USED_HW_CPU_LIST "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21" +#define USED_CPUS 24 +#define USED_HW_CPU_LIST "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23" #define TIMER_HZ 100000 #define PREEMPT_QUAN 5 diff --git a/scripts/params/shinjuku.params b/scripts/params/shinjuku.params index 482a54a..a85b7b6 100644 --- a/scripts/params/shinjuku.params +++ b/scripts/params/shinjuku.params @@ -1,2 +1,2 @@ #define USED_CPUS 21 -#define USED_HW_CPU_LIST "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20" +#define USED_HW_CPU_LIST "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21" diff --git a/scripts/plots/plot_rocksdb_server.py b/scripts/plots/plot_rocksdb_server.py new file mode 100644 index 0000000..def96a6 --- /dev/null +++ b/scripts/plots/plot_rocksdb_server.py @@ -0,0 +1,109 @@ +import os +import argparse +import numpy as np +import matplotlib.pyplot as plt +from matplotlib.ticker import (LogLocator, MultipleLocator, AutoMinorLocator) + +from common import * + + +def load_result(name): + f = open(name, "r") + results = [] + for i, line in enumerate(f.readlines()): + # if i % 2 == 0: + # continue + if line.strip() == "": + break + results.append(line.split(", ")) + + results = np.array(results) + throughputs = results[:, 2] + latency = results[:, -3] + return throughputs, latency + + +def plot(data=None, output=None): + bar_colors = [ + COLORS(0), + COLORS(2), + COLORS(4), + COLORS(1), + COLORS(3), + ] + markers = [ + ",:", + ".-", + "+-", + "x-", + "o-", + ] + labels = [ + "Shenango", + "Skyloft (no preemption)", + "Skyloft (20$\mu$s)", + "Skyloft (5$\mu$s)", + "Skyloft (5$\mu$s utimer)", + ] + + results = {} + res_dir = os.path.join(RES_DIR, data) + for f in os.listdir(res_dir): + thourghputs, latencies = load_result(os.path.join(res_dir, f)) + results[f] = {} + print(f, thourghputs, latencies) + for throughput, latency in zip(thourghputs, latencies): + results[f][float(throughput) / 1000] = float(latency) + + fig = plt.figure(figsize=(6, 2.5)) + + ax1 = fig.add_subplot(1, 1, 1) + ax1.grid(which="major", axis="y", linestyle=":", alpha=0.5, zorder=0) + + ax1.set_xlim(0, 45) + ax1.set_xticks([0, 10, 20, 30, 40]) + ax1.xaxis.set_minor_locator(MultipleLocator(2.5)) + + ax1.set_ylim(0, 200) + ax1.set_yticks([0, 50, 100, 150, 200]) + ax1.yaxis.set_minor_locator(MultipleLocator(25)) + + X=np.linspace(0,50,10) + Y=np.ones(X.size) + line, = ax1.plot(X, 50 * Y, color = 'black', linewidth=1, linestyle="-") + line.set_dashes((5, 5)) + + for i, e in enumerate(["shenango", "skyloft_nopre", "skyloft_20us", "skyloft_5us", "skyloft_5us_utimer"]): + # if e == "skyloft_nopre": + # continue + ax1.plot( + list(results[e].keys()), + list(results[e].values()), + markers[i], + label=labels[i], + zorder=3, + linewidth=1, + markersize=4, + markeredgewidth=1, + color=bar_colors[i], + ) + + # Create a unique legend + handles, labels = plt.gca().get_legend_handles_labels() + by_label = dict(zip(labels, handles)) + leg = plt.legend( + by_label.values(), by_label.keys(), loc="best", ncol=1, frameon=False, + ) + leg.get_frame().set_linewidth(0.0) + + fig.supylabel("99.9% Slowdown", x=0.01) + fig.supxlabel("Throughput (kRPS)", y=0.005) + + plt.tight_layout() + plt.subplots_adjust(top=0.97, bottom=0.18, left=0.11, right=0.97) + plt.savefig(output) + plt.show() + + +if __name__ == "__main__": + plot("rocksdb/50-get-50-scan", "rocksdb_server.pdf") diff --git a/scripts/plots/plot_schbench.py b/scripts/plots/plot_schbench.py index 5720821..fc719e3 100644 --- a/scripts/plots/plot_schbench.py +++ b/scripts/plots/plot_schbench.py @@ -14,24 +14,28 @@ FNAMES = [ "linux_rr", "linux_cfs", + "linux_cfs_opt", "skyloft_rr50us", "skyloft_cfs50us", ] LABELS = [ "Linux-RR", "Linux-CFS", + "Linux-CFS-opt", "Skyloft-RR", "Skyloft-CFS", ] MARKERS = [ ".:", "+--", + "*--", "x-", "o-", ] COLORS = [ COLORS(0), COLORS(4), + COLORS(2), COLORS(1), COLORS(3), ] @@ -90,6 +94,7 @@ def plot(data=None, output=None): plt.legend(handles, labels, loc='lower right', bbox_to_anchor=(1, -0.03), ncol=1, + fontsize=8, frameon=False, handlelength=2.5, ) diff --git a/synthetic/rocksdb/common.h b/synthetic/rocksdb/common.h index 1ccbded..0d5578b 100644 --- a/synthetic/rocksdb/common.h +++ b/synthetic/rocksdb/common.h @@ -69,7 +69,10 @@ static inline double max_throughput() return USEC_PER_SEC / mean_service_time_us() * FLAGS_num_workers; } -static inline double target_throughput() { return max_throughput() * FLAGS_load; } +static inline double target_throughput() +{ + return max_throughput() * FLAGS_load; +} void write_lat_results_detailed(int issued, request_t *reqs); void write_lat_results(int issued, request_t *reqs); diff --git a/synthetic/rocksdb/native.cc b/synthetic/rocksdb/native.cc deleted file mode 100644 index b1f87d1..0000000 --- a/synthetic/rocksdb/native.cc +++ /dev/null @@ -1,301 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "random.h" - -#define SQ 1 -// #define MQ 1 - -enum { - IDLE, - RUNNING, - FINISHED, - PREEMPTED, -}; - -typedef struct { - /* Bound to an isolated CPU */ - int cpu_id; - /* Database handle */ - rocksdb_t *db; - /* Pointer to dispatcher */ - void *dispatcher; - /* Worker running status */ - int status; -#ifdef MQ - /* When a new request arrives */ - __nsec next; - /* Track allocated requests */ - request_t *requests; - list_head req_list; - int issued; -#endif -} __aligned(CACHE_LINE_SIZE) worker_t; - -typedef struct { -#ifdef SQ - /* When a new request arrives */ - __nsec next; - /* Track allocated requests */ - request_t *requests; - int issued; - list_head req_list; - spinlock_t req_lock; -#endif - /* Track worker status */ - worker_t *workers; -} dispatcher_t; - -dispatcher_t *dispatcher_create(rocksdb_t *db); -void dispatcher_destroy(dispatcher_t *dispatcher); -void do_dispatching(dispatcher_t *dispatcher); - -dispatcher_t *dispatcher_create(rocksdb_t *db) -{ - int i, j; - dispatcher_t *dispatcher; - request_t *req; - - int target_tput = target_throughput(); - int num_reqs = target_tput * FLAGS_run_time * 2; - - dispatcher = (dispatcher_t *)malloc(sizeof(dispatcher_t)); -#ifdef SQ - dispatcher->next = 0; - dispatcher->requests = (request_t *)malloc(sizeof(request_t) * num_reqs); - - double timestamp = 0; - for (i = 0; i < num_reqs; i++) { - timestamp += random_exponential_distribution(); - init_request_bimodal(&dispatcher->requests[i], FLAGS_range_query_ratio, - FLAGS_range_query_size); - dispatcher->requests[i].gen_time = timestamp * NSEC_PER_USEC; - } - list_head_init(&dispatcher->req_list); - spin_lock_init(&dispatcher->req_lock); - dispatcher->issued = 0; -#endif - dispatcher->workers = (worker_t *)malloc(sizeof(worker_t) * FLAGS_num_workers); - for (i = 0; i < FLAGS_num_workers; i++) { - dispatcher->workers[i].cpu_id = i; - dispatcher->workers[i].db = db; - dispatcher->workers[i].dispatcher = (void *)dispatcher; - dispatcher->workers[i].status = IDLE; -#ifdef MQ - dispatcher->workers[i].requests = (request_t *)malloc(sizeof(request_t) * num_reqs); - for (j = 0; j < num_reqs; j++) init_request(&dispatcher->workers[i].requests[j]); - dispatcher->workers[i].issued = 0; - dispatcher->workers[i].next = 0; - list_head_init(&dispatcher->workers[i].req_list); -#endif - } - - return dispatcher; -} - -void dispatcher_destroy(dispatcher_t *dispatcher) -{ - int i; - - free(dispatcher->workers); -#ifdef SQ - free(dispatcher->requests); -#elif MQ - for (i = 0; i < FLAGS_num_cpus; i++) free(dispatcher->workers[i].requests); -#endif - free(dispatcher); -} - -#ifdef SQ -void poll_synthetic_network(dispatcher_t *dispatcher, __nsec start_time) -{ - spin_lock(&dispatcher->req_lock); - request_t *req = &dispatcher->requests[dispatcher->issued]; - - if (now_ns() < start_time + req->gen_time) { - spin_unlock(&dispatcher->req_lock); - return; - } - - req->gen_time += start_time; - req->recv_time = now_ns(); - dispatcher->issued++; - - list_add_tail(&dispatcher->req_list, &req->link); - spin_unlock(&dispatcher->req_lock); -} -#elif MQ -void poll_synthetic_network(dispatcher_t *dispatcher) -{ - request_t *req; - worker_t *worker = &dispatcher->workers[sl_current_cpu_id()]; - - if (now_ns() < worker->next) - return; - - // Avoid issues due to double precision; random generator might be slow - worker->next = now_ns() + NSEC_PER_USEC * random_exponential_distribution(); - - req = &worker->requests[worker->issued++]; - list_add_tail(&worker->req_list, &req->link); - req->recv_time = now_ns(); -} -#endif - -/* Run-to-complete request handler */ -static void* request_handler(void *arg) -{ - request_t *req; - worker_t *worker = (worker_t *)arg; - dispatcher_t *dispatcher = (dispatcher_t *)worker->dispatcher; - -#ifdef SQ - spin_lock(&dispatcher->req_lock); - req = list_pop(&dispatcher->req_list, request_t, link); - spin_unlock(&dispatcher->req_lock); -#elif MQ - req = list_pop(&worker->req_list, request_t, link); -#endif - - if (req == NULL) { - worker->status = IDLE; - return 0; - } - - req->start_time = now_ns(); - if (req->type == ROCKSDB_GET) { - rocksdb_handle_get(worker->db, req); - } else if (req->type == ROCKSDB_RANGE) { - rocksdb_handle_range_query(worker->db, req); - } - req->end_time = now_ns(); - - worker->status = FINISHED; - return 0; -} - -static __nsec global_start; - -static void* worker_percpu(void *arg) -{ - request_t *req; - worker_t *worker = (worker_t *)arg; - dispatcher_t *dispatcher = (dispatcher_t *)worker->dispatcher; - assert(worker != NULL); - - printf("Worker %d is running ...\n", worker->cpu_id); - - __nsec start = now_ns(); - __nsec end = now_ns() + FLAGS_run_time * NSEC_PER_SEC; - while (now_ns() < end) { - poll_synthetic_network(dispatcher, start); - - worker->status = RUNNING; - sl_task_spawn(request_handler, (void *)worker, 0); - while (worker->status == RUNNING) sl_task_yield(); - } - return 0; -} - -void do_dispatching(dispatcher_t *dispatcher) -{ - for (int i = 1; i < FLAGS_num_workers; i++) { - sl_task_spawn_oncpu(i, worker_percpu, (void *)&dispatcher->workers[i], 0); - } - worker_percpu((void *)&dispatcher->workers[0]); -} - -static void* experiment_main(void *arg) -{ - rocksdb_t *db; - worker_t *curr_worker; - dispatcher_t *dispatcher; - int i, j; - - if (FLAGS_load < 0 || FLAGS_load > 1) { - printf("Invalid load: %f\n", FLAGS_load); - return (void *)-EINVAL; - } - if (FLAGS_get_service_time < 0 || FLAGS_get_service_time > 1000) { - printf("Invalid get_service_time: %f\n", FLAGS_get_service_time); - return (void *)-EINVAL; - } - - printf("Experiment running on CPU %d, num workers: %d\n", sl_current_cpu_id(), - FLAGS_num_workers); - - // TODO: multiple load dispatchers - printf("RocksDB path: %s\n", FLAGS_rocksdb_path.c_str()); - printf("Initializing RocksDB...\n"); - db = rocksdb_init(FLAGS_rocksdb_path.c_str(), FLAGS_rocksdb_cache_size); - if (FLAGS_bench_request) - benchmark_request(db); - - // TODO: RQ might be drained - random_init(); - double mean_arrive_time_us = 1e6 / target_throughput(); - random_exponential_distribution_init(1.0 / mean_arrive_time_us); - - printf("Initializing load dispatcher...\n"); - dispatcher = dispatcher_create(db); - - __nsec start = now_ns(); - for (i = 0; i < 10000; i++) random_exponential_distribution(); - printf("Benchmarking random generator: %.3f ns\n", (double)(now_ns() - start) / 10000); - - printf("Generating requests...\n"); - do_dispatching(dispatcher); - -#ifdef SQ - write_lat_results_detailed(dispatcher->issued, dispatcher->requests); -#elif MQ - int issued = 0; - int num_reqs = target_throughput() * FLAGS_run_time * FLAGS_num_cpus; - request_t *requests = (request_t *)malloc(sizeof(request_t) * num_reqs); - for (i = 0; i < FLAGS_num_cpus; i++) - for (j = 0; j < dispatcher->workers[i].issued; j++) { - if (issued > num_reqs) - break; - requests[issued++] = dispatcher->workers[i].requests[j]; - } - write_lat_results_detailed(issued, requests); -#endif - dispatcher_destroy(dispatcher); - rocksdb_close(db); - printf("Experiment exits gracefully.\n"); - return 0; -} - -int main(int argc, char **argv) -{ - gflags::SetUsageMessage("test_rocksdb [options]"); - gflags::ParseCommandLineFlags(&argc, &argv, true); - gflags::ShutDownCommandLineFlags(); - - if (FLAGS_num_workers > USED_CPUS) { - printf("Too many CPUs %d > %d\n", FLAGS_num_workers, USED_CPUS); - return 0; - } - - sl_libos_start(experiment_main, NULL); -} diff --git a/synthetic/rocksdb/shinjuku.cc b/synthetic/rocksdb/shinjuku.cc index 3637c1c..a1efb2f 100644 --- a/synthetic/rocksdb/shinjuku.cc +++ b/synthetic/rocksdb/shinjuku.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include "common.h" #include "random.h" diff --git a/synthetic/rocksdb/shinjuku_old.cc b/synthetic/rocksdb/shinjuku_old.cc deleted file mode 100644 index 1efa8e6..0000000 --- a/synthetic/rocksdb/shinjuku_old.cc +++ /dev/null @@ -1,311 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "jbsq.h" -#include "random.h" - -enum { - IDLE, - RUNNING, - FINISHED, - PREEMPTED, -}; - -typedef struct { -} jbsq_t; - -typedef struct { - /* Bound to an isolated CPU */ - int cpu_id; -#ifdef MQ - list_head reqs; - spinlock_t req_lock; -#elif JBSQ_K > 1 - /* Requests to handle */ - JBSQ(request_t *, reqs); -#else - request_t *req; -#endif - /* Database handle */ - rocksdb_t *db; - /* Worker running status */ - int status; -} __aligned(CACHE_LINE_SIZE) worker_t; - -typedef struct { - /* When a new request arrives */ - __nsec next; - /* Track allocated requests */ - request_t *requests; - int issued; - list_head req_list; - /* Track worker status */ - worker_t *workers; -} dispatcher_t; - -dispatcher_t *dispatcher_create(rocksdb_t *db); -void dispatcher_destroy(dispatcher_t *dispatcher); -void do_dispatching(dispatcher_t *dispatcher); - -dispatcher_t *dispatcher_create(rocksdb_t *db) -{ - int i; - dispatcher_t *dispatcher; - request_t *req; - bool range_query = false; - - int target_tput = target_throughput(); - int num_reqs = target_tput * FLAGS_run_time * 2; - - dispatcher = (dispatcher_t *)malloc(sizeof(dispatcher_t)); - dispatcher->requests = (request_t *)malloc(sizeof(request_t) * num_reqs); - - double timestamp = 0; - for (i = 0; i < num_reqs; i++) { - timestamp += random_exponential_distribution(); - init_request_bimodal(&dispatcher->requests[i], FLAGS_range_query_ratio, - FLAGS_range_query_size); - dispatcher->requests[i].gen_time = timestamp * NSEC_PER_USEC; - } - list_head_init(&dispatcher->req_list); - dispatcher->issued = 0; - dispatcher->workers = (worker_t *)malloc(sizeof(worker_t) * (FLAGS_num_workers + 1)); - for (i = 1; i < FLAGS_num_workers + 1; i++) { - dispatcher->workers[i].cpu_id = i; - dispatcher->workers[i].status = IDLE; - dispatcher->workers[i].db = db; -#ifdef MQ - list_head_init(&dispatcher->workers[i].reqs); - spin_lock_init(&dispatcher->workers[i].req_lock); -#elif JBSQ_K > 1 - JBSQ_INIT(&dispatcher->workers[i].reqs); -#endif - } - - return dispatcher; -} - -void dispatcher_destroy(dispatcher_t *dispatcher) -{ - free(dispatcher->workers); - free(dispatcher->requests); - free(dispatcher); -} - -void poll_synthetic_network(dispatcher_t *dispatcher, __nsec start_time) -{ - int i; - request_t *req = &dispatcher->requests[dispatcher->issued]; - - if (now_ns() < start_time + req->gen_time) - return; - - req->gen_time += start_time; - req->recv_time = now_ns(); - dispatcher->issued++; - -#ifdef MQ - // Choose a worker queue at random - i = (rand() % FLAGS_num_workers) + 1; - spin_lock(&dispatcher->workers[i].req_lock); - list_add_tail(&dispatcher->workers[i].reqs, &req->link); - spin_unlock(&dispatcher->workers[i].req_lock); - // printf("PUSH %d %p\n", i, req); -#else - list_add_tail(&dispatcher->req_list, &req->link); -#endif -} - -/* Run-to-complete request handler */ -static void worker_request_handler(void *arg) -{ - request_t *req; - worker_t *worker = (worker_t *)arg; - assert(worker != NULL && sl_current_cpu_id() == worker->cpu_id); - -#ifdef MQ - spin_lock(&worker->req_lock); - req = list_pop(&worker->reqs, request_t, link); - spin_unlock(&worker->req_lock); - // printf("POP %d %p\n", sl_current_cpu_id(), req); -#elif JBSQ_K > 1 - req = JBSQ_POP(&worker->reqs); -#else - req = worker->req; -#endif - - req->start_time = now_ns(); - if (req->type == ROCKSDB_GET) { - rocksdb_handle_get(worker->db, req); - } else if (req->type == ROCKSDB_RANGE) { - rocksdb_handle_range_query(worker->db, req); - } - req->end_time = now_ns(); - - worker->status = FINISHED; - // printf("START %lu END %lu\n", req->start_time, req->end_time); -} - -#if JBSQ_K > 1 && !defined(MQ) -static inline void choose_shortest(dispatcher_t *dispatcher) -{ - int i, min_i, len, min_len; - request_t *req; - - min_len = INT_MAX; - for (i = 1; i < FLAGS_num_workers + 1; i++) { - len = JBSQ_LEN(&dispatcher->workers[i].reqs); - if (len < min_len && len < JBSQ_K) { - min_len = len; - min_i = i; - } - } - - if (min_len == INT_MAX) - return; - - req = list_pop(&dispatcher->req_list, request_t, link); - if (req != NULL) - JBSQ_PUSH(&dispatcher->workers[min_i].reqs, req); -} -#endif - -static inline void handle_worker(dispatcher_t *dispatcher, int i) -{ - request_t *req; - worker_t *worker = &dispatcher->workers[i]; - -#ifdef MQ - if (worker->status != RUNNING && !list_empty(&worker->reqs)) { - worker->status = RUNNING; - sl_task_spawn_oncpu(i, worker_request_handler, (void *)worker, 0); - } -#elif JBSQ_K > 1 - if (worker->status != RUNNING && !JBSQ_EMPTY(&worker->reqs)) { - worker->status = RUNNING; - sl_task_spawn_oncpu(i, worker_request_handler, (void *)worker, 0); - } -#else - if (worker->status != RUNNING) { - worker->req = list_pop(&dispatcher->req_list, request_t, link); - if (worker->req != NULL) { - worker->status = RUNNING; - sl_task_spawn_oncpu(i, worker_request_handler, (void *)worker, 0); - } - } -#endif -} - -void do_dispatching(dispatcher_t *dispatcher) -{ - int i; - request_t *req; - worker_t *worker; - __nsec start; - int min_len, min_i; - - start = now_ns(); - - for (;;) { - poll_synthetic_network(dispatcher, start); -#if JBSQ_K > 1 && !defined(MQ) - choose_shortest(dispatcher); -#endif - for (i = 1; i < FLAGS_num_workers + 1; ++i) handle_worker(dispatcher, i); - - /* Terminate all workers */ - if (now_ns() - start > FLAGS_run_time * NSEC_PER_SEC) - break; - } - printf("Dispatcher %d\n", dispatcher->issued); -} - -static void experiment_main(void *arg) -{ - rocksdb_t *db; - worker_t *curr_worker; - dispatcher_t *dispatcher; - result_t result; - FILE *output; - int i; - - if (FLAGS_load < 0 || FLAGS_load > 1) { - printf("Invalid load: %f\n", FLAGS_load); - return; - } - if (FLAGS_get_service_time < 0 || FLAGS_get_service_time > 1000) { - printf("Invalid get_service_time: %f\n", FLAGS_get_service_time); - return; - } - - printf("Dispatcher running on CPU %d, num workers: %d\n", sl_current_cpu_id(), - FLAGS_num_workers); - - // TODO: multiple load dispatchers - printf("RocksDB path: %s\n", FLAGS_rocksdb_path.c_str()); - printf("Initializing RocksDB...\n"); - db = rocksdb_init(FLAGS_rocksdb_path.c_str(), FLAGS_rocksdb_cache_size); - if (FLAGS_bench_request) - benchmark_request(db); - - // TODO: RQ might be drained - random_init(); - double mean_arrive_time_us = 1e6 / target_throughput(); - random_exponential_distribution_init(1.0 / mean_arrive_time_us); - - printf("Initializing load dispatcher...\n"); - dispatcher = dispatcher_create(db); - - __nsec start = now_ns(); - for (i = 0; i < 10000; i++) random_exponential_distribution(); - printf("Benchmarking random generator: %.3f ns\n", (double)(now_ns() - start) / 10000); - - printf("Generating requests...\n"); - do_dispatching(dispatcher); - - printf("Results: \n"); - result = get_result(dispatcher->issued, dispatcher->requests, FLAGS_run_time); - output = fopen((FLAGS_output_path + "/rocksdb_" + std::to_string(time(NULL))).c_str(), "w"); - assert(output != NULL); - output_result(result, output); - print_result(result); - - fclose(output); - dispatcher_destroy(dispatcher); - rocksdb_close(db); - printf("Experiment exits gracefully.\n"); -} - -int main(int argc, char **argv) -{ - gflags::SetUsageMessage("test_rocksdb [options]"); - gflags::ParseCommandLineFlags(&argc, &argv, true); - gflags::ShutDownCommandLineFlags(); - - if (FLAGS_num_workers + 1 > USED_CPUS) { - printf("Too many workers %d + 1 > %d\n", FLAGS_num_workers, USED_CPUS); - return 0; - } - - sl_libos_start(experiment_main, NULL); -} diff --git a/utils/bitmap.c b/utils/bitmap.c index d81aca2..fc0b313 100644 --- a/utils/bitmap.c +++ b/utils/bitmap.c @@ -2,27 +2,25 @@ * bitmap.c - a library for bit array manipulation */ -#include #include +#include -static __always_inline int -bitmap_find_next(unsigned long *bits, int nbits, int pos, bool invert) +static __always_inline int bitmap_find_next(unsigned long *bits, int nbits, int pos, bool invert) { - unsigned long val, mask = ~((1UL << BITMAP_POS_SHIFT(pos)) - 1); - int idx; + unsigned long val, mask = ~((1UL << BITMAP_POS_SHIFT(pos)) - 1); + int idx; - for (idx = align_down(pos, BITS_PER_LONG); - idx < nbits; idx += BITS_PER_LONG) { - val = bits[BITMAP_POS_IDX(idx)]; - if (invert) - val = ~val; - val &= mask; - if (val) - return MIN(idx + __builtin_ffsl(val) - 1, nbits); - mask = ~0UL; - } + for (idx = align_down(pos, BITS_PER_LONG); idx < nbits; idx += BITS_PER_LONG) { + val = bits[BITMAP_POS_IDX(idx)]; + if (invert) + val = ~val; + val &= mask; + if (val) + return MIN(idx + __builtin_ffsl(val) - 1, nbits); + mask = ~0UL; + } - return nbits; + return nbits; } /** @@ -35,7 +33,7 @@ bitmap_find_next(unsigned long *bits, int nbits, int pos, bool invert) */ int bitmap_find_next_cleared(unsigned long *bits, int nbits, int pos) { - return bitmap_find_next(bits, nbits, pos, true); + return bitmap_find_next(bits, nbits, pos, true); } /** @@ -48,5 +46,5 @@ int bitmap_find_next_cleared(unsigned long *bits, int nbits, int pos) */ int bitmap_find_next_set(unsigned long *bits, int nbits, int pos) { - return bitmap_find_next(bits, nbits, pos, false); + return bitmap_find_next(bits, nbits, pos, false); } diff --git a/utils/include/utils/bitmap.h b/utils/include/utils/bitmap.h index 2417c69..7c3f6cc 100644 --- a/utils/include/utils/bitmap.h +++ b/utils/include/utils/bitmap.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include #include #include diff --git a/utils/include/utils/byteorder.h b/utils/include/utils/byteorder.h index 1f86a8e..9ec8a1d 100644 --- a/utils/include/utils/byteorder.h +++ b/utils/include/utils/byteorder.h @@ -11,38 +11,31 @@ static inline uint16_t __bswap16(uint16_t val) { #ifdef HAS_BUILTIN_BSWAP - return __builtin_bswap16(val); + return __builtin_bswap16(val); #else - return (((val & 0x00ffU) << 8) | - ((val & 0xff00U) >> 8)); + return (((val & 0x00ffU) << 8) | ((val & 0xff00U) >> 8)); #endif } static inline uint32_t __bswap32(uint32_t val) { #ifdef HAS_BUILTIN_BSWAP - return __builtin_bswap32(val); + return __builtin_bswap32(val); #else - return (((val & 0x000000ffUL) << 24) | - ((val & 0x0000ff00UL) << 8) | - ((val & 0x00ff0000UL) >> 8) | - ((val & 0xff000000UL) >> 24)); + return (((val & 0x000000ffUL) << 24) | ((val & 0x0000ff00UL) << 8) | + ((val & 0x00ff0000UL) >> 8) | ((val & 0xff000000UL) >> 24)); #endif } static inline uint64_t __bswap64(uint64_t val) { #ifdef HAS_BUILTIN_BSWAP - return __builtin_bswap64(val); + return __builtin_bswap64(val); #else - return (((val & 0x00000000000000ffULL) << 56) | - ((val & 0x000000000000ff00ULL) << 40) | - ((val & 0x0000000000ff0000ULL) << 24) | - ((val & 0x00000000ff000000ULL) << 8) | - ((val & 0x000000ff00000000ULL) >> 8) | - ((val & 0x0000ff0000000000ULL) >> 24) | - ((val & 0x00ff000000000000ULL) >> 40) | - ((val & 0xff00000000000000ULL) >> 56)); + return (((val & 0x00000000000000ffULL) << 56) | ((val & 0x000000000000ff00ULL) << 40) | + ((val & 0x0000000000ff0000ULL) << 24) | ((val & 0x00000000ff000000ULL) << 8) | + ((val & 0x000000ff00000000ULL) >> 8) | ((val & 0x0000ff0000000000ULL) >> 24) | + ((val & 0x00ff000000000000ULL) >> 40) | ((val & 0xff00000000000000ULL) >> 56)); #endif } @@ -52,42 +45,42 @@ static inline uint64_t __bswap64(uint64_t val) #if __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_le16(x) (x) -#define cpu_to_le32(x) (x) -#define cpu_to_le64(x) (x) -#define cpu_to_be16(x) (__bswap16(x)) -#define cpu_to_be32(x) (__bswap32(x)) -#define cpu_to_be64(x) (__bswap64(x)) +#define cpu_to_le16(x) (x) +#define cpu_to_le32(x) (x) +#define cpu_to_le64(x) (x) +#define cpu_to_be16(x) (__bswap16(x)) +#define cpu_to_be32(x) (__bswap32(x)) +#define cpu_to_be64(x) (__bswap64(x)) -#define le16_to_cpu(x) (x) -#define le32_to_cpu(x) (x) -#define le64_to_cpu(x) (x) -#define be16_to_cpu(x) (__bswap16(x)) -#define be32_to_cpu(x) (__bswap32(x)) -#define be64_to_cpu(x) (__bswap64(x)) +#define le16_to_cpu(x) (x) +#define le32_to_cpu(x) (x) +#define le64_to_cpu(x) (x) +#define be16_to_cpu(x) (__bswap16(x)) +#define be32_to_cpu(x) (__bswap32(x)) +#define be64_to_cpu(x) (__bswap64(x)) #else /* __BYTE_ORDER == __LITLE_ENDIAN */ -#define cpu_to_le16(x) (__bswap16(x)) -#define cpu_to_le32(x) (__bswap32(x)) -#define cpu_to_le64(x) (__bswap64(x)) -#define cpu_to_be16(x) (x) -#define cpu_to_be32(x) (x) -#define cpu_to_be64(x) (x) +#define cpu_to_le16(x) (__bswap16(x)) +#define cpu_to_le32(x) (__bswap32(x)) +#define cpu_to_le64(x) (__bswap64(x)) +#define cpu_to_be16(x) (x) +#define cpu_to_be32(x) (x) +#define cpu_to_be64(x) (x) -#define le16_to_cpu(x) (__bswap16(x)) -#define le32_to_cpu(x) (__bswap32(x)) -#define le64_to_cpu(x) (__bswap64(x)) -#define be16_to_cpu(x) (x) -#define be32_to_cpu(x) (x) -#define be64_to_cpu(x) (x) +#define le16_to_cpu(x) (__bswap16(x)) +#define le32_to_cpu(x) (__bswap32(x)) +#define le64_to_cpu(x) (__bswap64(x)) +#define be16_to_cpu(x) (x) +#define be32_to_cpu(x) (x) +#define be64_to_cpu(x) (x) #endif /* __BYTE_ORDER == __LITTLE_ENDIAN */ -#define ntoh16(x) (be16_to_cpu(x)) -#define ntoh32(x) (be32_to_cpu(x)) -#define ntoh64(x) (be64_to_cpu(x)) +#define ntoh16(x) (be16_to_cpu(x)) +#define ntoh32(x) (be32_to_cpu(x)) +#define ntoh64(x) (be64_to_cpu(x)) -#define hton16(x) (cpu_to_be16(x)) -#define hton32(x) (cpu_to_be32(x)) -#define hton64(x) (cpu_to_be64(x)) +#define hton16(x) (cpu_to_be16(x)) +#define hton32(x) (cpu_to_be32(x)) +#define hton64(x) (cpu_to_be64(x)) diff --git a/utils/include/utils/cksum.h b/utils/include/utils/cksum.h index f5bb26a..bb7175e 100644 --- a/utils/include/utils/cksum.h +++ b/utils/include/utils/cksum.h @@ -18,58 +18,58 @@ */ static inline uint16_t cksum_internet(const void *buf, int len) { - uint64_t sum; + uint64_t sum; - asm volatile("xorq %0, %0\n" + asm volatile("xorq %0, %0\n" - /* process 8 byte chunks */ - "movl %2, %%edx\n" - "shrl $3, %%edx\n" - "cmp $0, %%edx\n" - "jz 2f\n" - "1: adcq (%1), %0\n" - "leaq 8(%1), %1\n" - "decl %%edx\n" - "jne 1b\n" - "adcq $0, %0\n" + /* process 8 byte chunks */ + "movl %2, %%edx\n" + "shrl $3, %%edx\n" + "cmp $0, %%edx\n" + "jz 2f\n" + "1: adcq (%1), %0\n" + "leaq 8(%1), %1\n" + "decl %%edx\n" + "jne 1b\n" + "adcq $0, %0\n" - /* process 4 byte (if left) */ - "2: test $4, %2\n" - "je 3f\n" - "movl (%1), %%edx\n" - "addq %%rdx, %0\n" - "adcq $0, %0\n" - "leaq 4(%1), %1\n" + /* process 4 byte (if left) */ + "2: test $4, %2\n" + "je 3f\n" + "movl (%1), %%edx\n" + "addq %%rdx, %0\n" + "adcq $0, %0\n" + "leaq 4(%1), %1\n" - /* process 2 byte (if left) */ - "3: test $2, %2\n" - "je 4f\n" - "movzxw (%1), %%rdx\n" - "addq %%rdx, %0\n" - "adcq $0, %0\n" - "leaq 2(%1), %1\n" + /* process 2 byte (if left) */ + "3: test $2, %2\n" + "je 4f\n" + "movzxw (%1), %%rdx\n" + "addq %%rdx, %0\n" + "adcq $0, %0\n" + "leaq 2(%1), %1\n" - /* process 1 byte (if left) */ - "4: test $1, %2\n" - "je 5f\n" - "movzxb (%1), %%rdx\n" - "addq %%rdx, %0\n" - "adcq $0, %0\n" + /* process 1 byte (if left) */ + "4: test $1, %2\n" + "je 5f\n" + "movzxb (%1), %%rdx\n" + "addq %%rdx, %0\n" + "adcq $0, %0\n" - /* fold into 16-bit answer */ - "5: movq %0, %1\n" - "shrq $32, %0\n" - "addl %k1, %k0\n" - "adcl $0, %k0\n" - "movq %0, %1\n" - "shrl $16, %k0\n" - "addw %w1, %w0\n" - "adcw $0, %w0\n" - "not %0\n" + /* fold into 16-bit answer */ + "5: movq %0, %1\n" + "shrq $32, %0\n" + "addl %k1, %k0\n" + "adcl $0, %k0\n" + "movq %0, %1\n" + "shrl $16, %k0\n" + "addw %w1, %w0\n" + "adcw $0, %w0\n" + "not %0\n" - : "=&r"(sum), "=r"(buf) - : "r"(len), "1"(buf) : "%rdx", "cc", "memory"); + : "=&r"(sum), "=r"(buf) + : "r"(len), "1"(buf) + : "%rdx", "cc", "memory"); - return (uint16_t)sum; + return (uint16_t)sum; } - diff --git a/utils/include/utils/fxsave.h b/utils/include/utils/fxsave.h new file mode 100644 index 0000000..dd82f14 --- /dev/null +++ b/utils/include/utils/fxsave.h @@ -0,0 +1,107 @@ +/* + * fxsave.h - Save x87 FPU, MMX Technology, and SSE State. + * + * See https://www.felixcloutier.com/x86/fxsave. + */ + +/* + * From NetBSD: cpu_extended_state.h + * + * This file contains definitions of structures that match the memory layouts + * used on x86 processors to save floating point registers and other extended + * cpu states. + * + * This includes registers (etc) used by SSE/SSE2/SSE3/SSSE3/SSE4 and the later + * AVX instructions. + * + * The definitions are such that any future 'extended state' should be handled, + * provided the kernel doesn't need to know the actual contents. + * + * The actual structures the cpu accesses must be aligned to 16 bytes for FXSAVE + * and 64 for XSAVE. The types aren't aligned because copies do not need extra + * alignment. + * + * The slightly different layout saved by the i387 fsave is also defined. + * This is only normally written by pre Pentium II type cpus that don't + * support the fxsave instruction. + * + * Associated save instructions: + * FNSAVE: Saves x87 state in 108 bytes (original i387 layout). Then + * reinitializes the fpu. + * FSAVE: Encodes to FWAIT followed by FNSAVE. + * FXSAVE: Saves the x87 state and XMM (aka SSE) registers to the first + * 448 (max) bytes of a 512 byte area. This layout does not match + * that written by FNSAVE. + * XSAVE: Uses the same layout for the x87 and XMM registers, followed by + * a 64byte header and separate save areas for additional extended + * cpu states. The x87 state is always saved, the others + * conditionally. + * XSAVEOPT: Same as XSAVE but only writes the registers blocks that have + * been modified. + */ + +#pragma once + +#include + +#include +#include + +/* + * Layout for code/data pointers relating to FP exceptions. Marked 'packed' + * because they aren't always 64bit aligned. Since the x86 cpu supports + * misaligned accesses it isn't worth avoiding the 'packed' attribute. + */ +union fp_addr { + uint64_t fa_64; /* Linear address for 64bit systems */ + struct { + uint32_t fa_off; /* linear address for 32 bit */ + uint16_t fa_seg; /* code/data (etc) segment */ + uint16_t fa_opcode; /* last opcode (sometimes) */ + } fa_32; +} __packed __aligned(4); + +/* The x87 registers are 80 bits */ +struct fpacc87 { + uint64_t f87_mantissa; /* mantissa */ + uint16_t f87_exp_sign; /* exponent and sign */ +} __packed __aligned(2); + +/* The x87 registers padded out to 16 bytes for fxsave */ +struct fpaccfx { + struct fpacc87 r __aligned(16); +}; + +/* The SSE/SSE2 registers are 128 bits */ +struct xmmreg { + uint8_t xmm_bytes[16]; +}; + +/* + * FPU/MMX/SSE/SSE2 context (FXSAVE instruction). + */ +struct fxsave { + uint16_t fx_cw; /* FPU Control Word */ + uint16_t fx_sw; /* FPU Status Word */ + uint8_t fx_tw; /* FPU Tag Word (abridged) */ + uint8_t fx_zero; /* zero */ + uint16_t fx_opcode; /* FPU Opcode */ + union fp_addr fx_ip; /* FPU Instruction Pointer */ + union fp_addr fx_dp; /* FPU Data pointer */ + uint32_t fx_mxcsr; /* MXCSR Register State */ + uint32_t fx_mxcsr_mask; /* MXCSR_MASK */ + struct fpaccfx fx_87_ac[8]; /* 8 x87 registers */ + struct xmmreg fx_xmm[16]; /* XMM regs (8 in 32bit modes) */ + uint8_t fx_rsvd0[48]; + uint8_t fx_rsvd1[48]; /* Reserved for software */ +} __aligned(16); +BUILD_ASSERT(sizeof(struct fxsave) == 512); + +static inline void fxstate_init(struct fxsave *fxstate) +{ + assert(fxstate != NULL); + memset(fxstate, 0, sizeof(struct fxsave)); + fxstate->fx_cw = 0x37f; + fxstate->fx_tw = 0xff; + fxstate->fx_mxcsr = 0x1f80; +} diff --git a/utils/include/utils/hash.h b/utils/include/utils/hash.h index f5c2e61..2cdcca3 100644 --- a/utils/include/utils/hash.h +++ b/utils/include/utils/hash.h @@ -13,7 +13,6 @@ #include #include -#include static inline uint64_t __mm_crc32_u64(uint64_t crc, uint64_t val) { diff --git a/utils/include/utils/lrpc.h b/utils/include/utils/lrpc.h index d1e936c..f7d5aab 100644 --- a/utils/include/utils/lrpc.h +++ b/utils/include/utils/lrpc.h @@ -11,7 +11,6 @@ #include #include #include -#include struct lrpc_msg { uint64_t cmd; diff --git a/utils/include/utils/msgq.h b/utils/include/utils/msgq.h index bd702ab..a8e730e 100644 --- a/utils/include/utils/msgq.h +++ b/utils/include/utils/msgq.h @@ -9,7 +9,7 @@ #include #include #include -#include + #include #define MSGQ_SIZE 4096 diff --git a/utils/include/utils/queue.h b/utils/include/utils/queue.h index ace0f34..bfec9de 100644 --- a/utils/include/utils/queue.h +++ b/utils/include/utils/queue.h @@ -31,13 +31,25 @@ typedef struct { void *buf[QUEUE_CAP]; } queue_t; -static inline int queue_len(queue_t *queue) { return queue->tail - queue->head; } +static inline int queue_len(queue_t *queue) +{ + return queue->tail - queue->head; +} -static inline bool queue_is_empty(queue_t *queue) { return queue_len(queue) == 0; } +static inline bool queue_is_empty(queue_t *queue) +{ + return queue_len(queue) == 0; +} -static inline bool queue_is_full(queue_t *queue) { return queue_len(queue) >= QUEUE_CAP; } +static inline bool queue_is_full(queue_t *queue) +{ + return queue_len(queue) >= QUEUE_CAP; +} -static inline void *queue_head(queue_t *queue) { return queue->buf[queue->head & QUEUE_CAP_MASK]; } +static inline void *queue_head(queue_t *queue) +{ + return queue->buf[queue->head & QUEUE_CAP_MASK]; +} static inline int queue_push(queue_t *queue, void *item) { diff --git a/utils/include/utils/shm.h b/utils/include/utils/shm.h index 82fd891..0219a96 100644 --- a/utils/include/utils/shm.h +++ b/utils/include/utils/shm.h @@ -7,7 +7,6 @@ #include #include -#include /* * Shared memory pointer support. These are pointers that are passed across diff --git a/utils/include/utils/spinlock.h b/utils/include/utils/spinlock.h index 756a3de..1598b86 100644 --- a/utils/include/utils/spinlock.h +++ b/utils/include/utils/spinlock.h @@ -6,7 +6,6 @@ #include #include -#include typedef struct { volatile int locked; diff --git a/utils/include/utils/syscalls.h b/utils/include/utils/syscalls.h index 3dfc514..5740c77 100644 --- a/utils/include/utils/syscalls.h +++ b/utils/include/utils/syscalls.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include static inline pid_t _gettid() {