Skip to content

Commit 1be5afa

Browse files
committed
update and remove jvm deps
1 parent 9ac68ee commit 1be5afa

40 files changed

+325
-892
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ Cargo.lock
2323
.gradle
2424
build/
2525

26+
# VsCode stuff
27+
.vscode
28+
2629
# Ignore Gradle GUI config
2730
gradle-app.setting
2831

@@ -52,3 +55,4 @@ compile_commands.json
5255
CTestTestfile.cmake
5356
_depsv
5457

58+
cpp/out

Cargo.toml

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
[package]
22
name = "async_bench"
3-
version = "0.1.0"
4-
edition = "2018"
3+
version = "0.2.0"
4+
edition = "2021"
55

66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
9-
criterion = { version = "0.3", features = ["async_tokio"] }
9+
criterion = "0.4"
1010
rand = "0.8"
11-
core_affinity = "0.5"
11+
core_affinity = "0.8"
1212
byteorder = "1.4"
1313
libc = "0.2"
1414
lazy_static = "1.4"
15-
page_size = "0.4"
16-
thread-priority = "0.2"
15+
page_size = "0.5"
16+
thread-priority = "0.13"
17+
json = "0.12"
1718

1819
[profile.release]
1920
lto = true

README.md

+27-3
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,37 @@ For the coroutine server code, this is the kotlin version which is probably the
9898
All the coroutine version were written the same. The coroutine code suspends while the event loop spins on memory. When the coroutine code resumes w/ the new value, it writes it.
9999

100100

101-
### Suspend vs Resume
101+
## Suspend vs Resume
102+
103+
The code flow for the coroutine code looks like this :
104+
```mermaid
105+
stateDiagram
106+
state "Client Measures This" as time
107+
state time {
108+
SpinLoop --> Resume
109+
Resume --> WriteValue
110+
}
111+
WriteValue --> Suspend
112+
Suspend --> SpinLoop
113+
```
102114

103-
The code flow for the coroutine code looks like this `SpinLoop->Resume->WriteValue->Suspend::Loop` Since the client is measuring the time it takes from `SpinLoop` to `WriteValue`, it most likely isn't measuring the time `Suspend` takes. There is no reason to think the time to `Resume` is the same as to `Suspend`.
115+
Since the client is measuring the time it takes from `SpinLoop` to `WriteValue`, it most likely isn't measuring the time `Suspend` takes. There is no reason to think the time to `Resume` is the same as to `Suspend`.
104116

105117
If the event loop is dispatching the same event to multiple listeners, or had multiple events to dispatch, you bear the cost of both the suspend and resume for each event.
106118

107-
So I wrote two version of each coroutine. The version above is called the `Resume` version. The `Suspend` version code flow look like `SpinLoop->Suspend->WriteValue->Resume::Loop`. In the `Suspend` version the `SpinLoop` is in the coroutine code block, and the writing of the value is in the `eventLoop`.
119+
So I wrote two version of each coroutine. The version above is called the `Resume` version. The `Suspend` version code flow looks like :
120+
```mermaid
121+
stateDiagram
122+
state "Client Measures This" as time
123+
state time {
124+
SpinLoop --> Suspend
125+
Suspend --> WriteValue
126+
}
127+
WriteValue --> Resume
128+
Resume --> SpinLoop
129+
```
130+
131+
In the `Suspend` version the `SpinLoop` is in the coroutine code block, and the writing of the value is in the `eventLoop`.
108132

109133
### Callbacks
110134
The spin loop isn't a fair comparison to the coroutine code, so I added a callback version. I didn't write the reciprocal version of callback, like I did with the coroutine code. I'm just going to assume returning from a callback is cheap.

benches/bench_atomic.rs

+9-13
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ fn cpp_bench(c: &mut Criterion) {
8080
core_affinity::set_for_current(CoreId { id: CLIENT_CPU });
8181

8282
let mut child =
83-
async_bench::bench_utils::launch_local("cpp/target/release/atomicSpin", vec![SERVER_CPU].as_ref());
83+
async_bench::bench_utils::launch_local("cpp/out/atomicSpin", vec![SERVER_CPU].as_ref());
8484

8585
async_bench::bench_utils::run_bench(c, "atomic_spin", "cpp_atomic", &client);
8686

@@ -95,7 +95,7 @@ fn cpp_resume(c: &mut Criterion) {
9595
core_affinity::set_for_current(CoreId { id: CLIENT_CPU });
9696

9797
let mut child =
98-
async_bench::bench_utils::launch_local("cpp/target/release/asyncResume", vec![SERVER_CPU].as_ref());
98+
async_bench::bench_utils::launch_local("cpp/out/asyncResume", vec![SERVER_CPU].as_ref());
9999

100100
async_bench::bench_utils::run_bench(c, "atomic_spin", "cpp_resume", &client);
101101

@@ -110,7 +110,7 @@ fn cpp_suspend(c: &mut Criterion) {
110110
core_affinity::set_for_current(CoreId { id: CLIENT_CPU });
111111

112112
let mut child =
113-
async_bench::bench_utils::launch_local("cpp/target/release/asyncSuspend", vec![SERVER_CPU].as_ref());
113+
async_bench::bench_utils::launch_local("cpp/out/asyncSuspend", vec![SERVER_CPU].as_ref());
114114

115115
async_bench::bench_utils::run_bench(c, "atomic_spin", "cpp_suspend", &client);
116116

@@ -125,7 +125,7 @@ fn cpp_callback(c: &mut Criterion) {
125125
core_affinity::set_for_current(CoreId { id: CLIENT_CPU });
126126

127127
let mut child =
128-
async_bench::bench_utils::launch_local("cpp/target/release/atomicCallback", vec![SERVER_CPU].as_ref());
128+
async_bench::bench_utils::launch_local("cpp/out/atomicCallback", vec![SERVER_CPU].as_ref());
129129

130130
async_bench::bench_utils::run_bench(c, "atomic_spin", "cpp_callback", &client);
131131

@@ -208,7 +208,7 @@ fn kotlin_bench(c: &mut Criterion) {
208208
core_affinity::set_for_current(CoreId { id: CLIENT_CPU });
209209

210210
let mut child = async_bench::bench_utils::launch_local_java(
211-
"kotlin/app/build/libs/app-all.jar",
211+
"kotlin/servers.jar",
212212
"kotlin_servers.AtomicSpinKt",
213213
Some(async_bench::bench_utils::JAVA_OPTS.as_ref()),
214214
vec![SERVER_CPU].as_ref(),
@@ -226,7 +226,7 @@ fn kotlin_resume(c: &mut Criterion) {
226226
core_affinity::set_for_current(CoreId { id: CLIENT_CPU });
227227

228228
let mut child = async_bench::bench_utils::launch_local_java(
229-
"kotlin/app/build/libs/app-all.jar",
229+
"kotlin/servers.jar",
230230
"kotlin_servers.AsyncResumeKt",
231231
Some(async_bench::bench_utils::JAVA_OPTS.as_ref()),
232232
vec![SERVER_CPU].as_ref(),
@@ -244,7 +244,7 @@ fn kotlin_suspend(c: &mut Criterion) {
244244
core_affinity::set_for_current(CoreId { id: CLIENT_CPU });
245245

246246
let mut child = async_bench::bench_utils::launch_local_java(
247-
"kotlin/app/build/libs/app-all.jar",
247+
"kotlin/servers.jar",
248248
"kotlin_servers.AsyncSuspendKt",
249249
Some(async_bench::bench_utils::JAVA_OPTS.as_ref()),
250250
vec![SERVER_CPU].as_ref(),
@@ -260,9 +260,9 @@ fn kotlin_callback(c: &mut Criterion) {
260260
let client = MappedAtomics::new(true);
261261

262262
core_affinity::set_for_current(CoreId { id: CLIENT_CPU });
263-
263+
264264
let mut child = async_bench::bench_utils::launch_local_java(
265-
"kotlin/app/build/libs/app-all.jar",
265+
"kotlin/servers.jar",
266266
"kotlin_servers.AtomicCallbackKt",
267267
Some(async_bench::bench_utils::JAVA_OPTS.as_ref()),
268268
vec![SERVER_CPU].as_ref(),
@@ -276,10 +276,6 @@ fn kotlin_callback(c: &mut Criterion) {
276276

277277
criterion_group!(
278278
benches,
279-
rust_callback,
280-
rust_callback,
281-
rust_callback,
282-
rust_callback,
283279
cpp_bench,
284280
cpp_resume,
285281
cpp_suspend,

build_all.sh

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Things you need in your path:
2+
# - Rust tool chain (cargo, rustc, etc.)
3+
# - kotlinc version 1.8.20
4+
# - java version 19 or better
5+
# - zig version 0.10.1
6+
7+
# Tihs assumes your running from the root of the project
8+
#!/usr/bin/env sh
9+
10+
cargo build --release
11+
12+
cd kotlin/
13+
echo "$PWD"
14+
./build.sh
15+
cd ../cpp
16+
echo "$PWD"
17+
./build.sh
18+
cd ../zig
19+
echo "$PWD"
20+
zig build

cpp/CMakeLists.txt

-25
This file was deleted.

cpp/MappedAtomics.h

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
//
2-
// Created by jonross on 10/8/21.
3-
//
41

52
#ifndef CPP_MAPPEDATOMICS_H
63
#define CPP_MAPPEDATOMICS_H
@@ -13,6 +10,7 @@
1310
#include <cstring>
1411
#include <unistd.h>
1512
#include <atomic>
13+
#include <stdlib.h>
1614

1715
struct MappedAtomics {
1816
std::atomic<long unsigned int> *clientPtr;
@@ -34,13 +32,13 @@ struct MappedAtomics {
3432
S_IWUSR | S_IRGRP | S_IWGRP
3533
);
3634
if(shmFd <= 0 ) {
37-
std::cout << "shm_open failed. exiting : " << std::strerror(errno) << std::endl;
38-
throw std::system_error(errno, std::generic_category());
35+
std::cout << "shm_open failed. Is the benchmark running? exiting. error : " << std::strerror(errno) << std::endl;
36+
exit(-1);
3937
}
4038
// std::cout << "shm fd = " << shmFd << std::endl;
4139
if( ftruncate( shmFd, getpagesize() ) != 0 ) {
42-
std::cout << "ftruncate failed. exiting : " << std::strerror(errno) << std::endl;
43-
throw std::system_error(errno, std::generic_category());
40+
std::cout << "ftruncate failed. exiting. error : " << std::strerror(errno) << std::endl;
41+
exit(-1);
4442
}
4543

4644

cpp/asyncResume.cpp

+2-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//#define _GNU_SOURCE
22

33
#include <iostream>
4-
#include <sched.h>
54
#include <cstring>
65
#include "MappedAtomics.h"
76
#include <concepts>
@@ -44,21 +43,8 @@ asyncLoop( AsyncContext *context )
4443
}
4544

4645

47-
int main(int argc, char * argv[]) {
48-
49-
if(argc < 2) {
50-
std::cout << "must pass cpu # to run on. exiting." << std::endl;
51-
return -1;
52-
}
53-
auto cpuNum = std::stoul( argv[1]);
54-
55-
cpu_set_t cpuSet;
56-
CPU_ZERO( &cpuSet );
57-
CPU_SET(cpuNum, &cpuSet);
58-
if( sched_setaffinity(0, sizeof(cpuSet), &cpuSet) != 0 ) {
59-
std::cout << "set affinity failed with following error : " << std::strerror(errno) << std::endl;
60-
return -1;
61-
}
46+
#define UU __attribute__((unused))
47+
int main(UU int argc, UU char * argv[]) {
6248

6349
auto *atomic = new(MappedAtomics);
6450

cpp/asyncSuspend.cpp

+2-17
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
//#define _GNU_SOURCE
22

33
#include <iostream>
4-
#include <sched.h>
5-
#include <cstring>
64
#include "MappedAtomics.h"
75
#include <concepts>
86
#include <coroutine>
@@ -46,21 +44,8 @@ asyncLoop( AsyncContext *context )
4644
}
4745

4846

49-
int main(int argc, char * argv[]) {
50-
51-
if(argc < 2) {
52-
std::cout << "must pass cpu # to run on. exiting." << std::endl;
53-
return -1;
54-
}
55-
auto cpuNum = std::stoul( argv[1]);
56-
57-
cpu_set_t cpuSet;
58-
CPU_ZERO( &cpuSet );
59-
CPU_SET(cpuNum, &cpuSet);
60-
if( sched_setaffinity(0, sizeof(cpuSet), &cpuSet) != 0 ) {
61-
std::cout << "set affinity failed with following error : " << std::strerror(errno) << std::endl;
62-
return -1;
63-
}
47+
#define UU __attribute__((unused))
48+
int main(UU int argc, UU char * argv[]) {
6449

6550
auto *atomic = new(MappedAtomics);
6651

cpp/atomicCallback.cpp

+2-18
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
//#define _GNU_SOURCE
22

33
#include <iostream>
4-
#include <sched.h>
5-
#include <cstring>
6-
#include <c++/9/functional>
74
#include <optional>
85
#include "MappedAtomics.h"
96

@@ -42,21 +39,8 @@ class EventLoop {
4239
}
4340
};
4441

45-
int main(int argc, char * argv[]) {
46-
47-
if(argc < 2) {
48-
std::cout << "must pass cpu # to run on. exiting." << std::endl;
49-
return -1;
50-
}
51-
auto cpuNum = std::stoul( argv[1]);
52-
53-
cpu_set_t cpuSet;
54-
CPU_ZERO( &cpuSet );
55-
CPU_SET(cpuNum, &cpuSet);
56-
if( sched_setaffinity(0, sizeof(cpuSet), &cpuSet) != 0 ) {
57-
std::cout << "set affinity failed with following error : " << std::strerror(errno) << std::endl;
58-
return -1;
59-
}
42+
#define UU __attribute__((unused))
43+
int main(UU int argc, UU char * argv[]) {
6044

6145
auto *atomic = new(MappedAtomics);
6246

cpp/atomicSpin.cpp

+2-16
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,11 @@
11
//#define _GNU_SOURCE
22

33
#include <iostream>
4-
#include <sched.h>
54
#include <cstring>
65
#include "MappedAtomics.h"
76

8-
int main(int argc, char * argv[]) {
9-
10-
if(argc < 2) {
11-
std::cout << "must pass cpu # to run on. exiting." << std::endl;
12-
return -1;
13-
}
14-
auto cpuNum = std::stoul( argv[1]);
15-
16-
cpu_set_t cpuSet;
17-
CPU_ZERO( &cpuSet );
18-
CPU_SET(cpuNum, &cpuSet);
19-
if( sched_setaffinity(0, sizeof(cpuSet), &cpuSet) != 0 ) {
20-
std::cout << "set affinity failed with following error : " << std::strerror(errno) << std::endl;
21-
return -1;
22-
}
7+
#define UU __attribute__((unused))
8+
int main(UU int argc, UU char * argv[]) {
239

2410
auto *atomic = new(MappedAtomics);
2511

cpp/build

-4
This file was deleted.

cpp/build.sh

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CMD="zig c++ -std=c++20 -lrt -Wall -Wextra -Wconversion -Wsign-conversion -Ofast -finline-functions"
2+
3+
`mkdir -p out`
4+
5+
`$CMD -oout/atomicSpin atomicSpin.cpp MappedAtomics.cpp`
6+
`$CMD -oout/asyncResume asyncResume.cpp MappedAtomics.cpp`
7+
`$CMD -oout/asyncSuspend asyncSuspend.cpp MappedAtomics.cpp`
8+
`$CMD -oout/atomicCallback atomicCallback.cpp MappedAtomics.cpp`

cpp/setup

-6
This file was deleted.

0 commit comments

Comments
 (0)