Skip to content

Commit 5659188

Browse files
committed
vgc: 10% speed up
1 parent 0c9a61e commit 5659188

8 files changed

Lines changed: 175 additions & 79 deletions

File tree

bench/README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ V version: 0.5.1.
55

66
## GC: Boehm vs VGC
77

8-
Compares Boehm GC (`-gc boehm`) against V's built-in concurrent tri-color mark-and-sweep (`-gc vgc`).
8+
Compares Boehm GC (`-gc boehm`) against V's built-in concurrent tri-color
9+
mark-and-sweep (`-gc vgc`).
910
5 iterations per test, median reported.
1011

1112
```
@@ -15,18 +16,18 @@ v run bench/bench_gc.v
1516
```
1617
test boehm vgc ratio
1718
———————————————————————————————————————————— ————————— ————————— —————————
18-
small allocs (1000000x string) 41 ms 59 ms 1.44x
19-
tree build+walk (depth=18, 10x) 49 ms 156 ms 3.18x
20-
array grow (100x 100000 pushes) 8 ms 33 ms 4.13x
21-
map insert (20x 10k entries) 20 ms 31 ms 1.55x
22-
mixed workload (50 rounds) 10 ms 21 ms 2.10x
19+
small allocs (1000000x string) 43 ms 52 ms 1.21x
20+
tree build+walk (depth=18, 10x) 46 ms 125 ms 2.72x
21+
array grow (100x 100000 pushes) 7 ms 30 ms 4.29x
22+
map insert (20x 10k entries) 20 ms 27 ms 1.35x
23+
mixed workload (50 rounds) 10 ms 16 ms 1.60x
2324
2425
heap usage:
25-
boehm: 29856 KB allocated, 29312 KB free
26+
boehm: 29856 KB allocated, 29020 KB free
2627
vgc: 131072 KB allocated, 0 KB free
2728
```
2829

29-
Boehm is 1.4x-4x faster across all workloads and uses ~4x less heap.
30+
Boehm is still 1.2x-4.3x faster across these workloads and uses ~4x less heap.
3031

3132
## Closures
3233

thirdparty/vgc/vgc_platform.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,59 @@ static inline void vgc_set_cache_idx(int idx) { _vgc_cache_idx = idx; }
112112
static inline void* vgc_get_sp(void) { return __builtin_frame_address(0); }
113113
#endif
114114

115+
// ============================================================
116+
// Stack bounds
117+
// ============================================================
118+
#if defined(__APPLE__)
119+
#include <pthread.h>
120+
static inline int vgc_get_stack_bounds(uintptr_t* lo, uintptr_t* hi) {
121+
void* stack_hi = pthread_get_stackaddr_np(pthread_self());
122+
size_t stack_size = pthread_get_stacksize_np(pthread_self());
123+
if (stack_hi == NULL || stack_size == 0) return 0;
124+
*hi = (uintptr_t)stack_hi;
125+
*lo = *hi - stack_size;
126+
return 1;
127+
}
128+
#elif defined(__linux__) || defined(__ANDROID__)
129+
#include <pthread.h>
130+
static inline int vgc_get_stack_bounds(uintptr_t* lo, uintptr_t* hi) {
131+
pthread_attr_t attr;
132+
if (pthread_getattr_np(pthread_self(), &attr) != 0) return 0;
133+
void* stack_lo = NULL;
134+
size_t stack_size = 0;
135+
int ok = pthread_attr_getstack(&attr, &stack_lo, &stack_size) == 0 && stack_lo != NULL && stack_size != 0;
136+
pthread_attr_destroy(&attr);
137+
if (!ok) return 0;
138+
*lo = (uintptr_t)stack_lo;
139+
*hi = *lo + stack_size;
140+
return 1;
141+
}
142+
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
143+
#include <pthread.h>
144+
static inline int vgc_get_stack_bounds(uintptr_t* lo, uintptr_t* hi) {
145+
pthread_attr_t attr;
146+
if (pthread_attr_init(&attr) != 0) return 0;
147+
if (pthread_attr_get_np(pthread_self(), &attr) != 0) {
148+
pthread_attr_destroy(&attr);
149+
return 0;
150+
}
151+
void* stack_lo = NULL;
152+
size_t stack_size = 0;
153+
int ok = pthread_attr_getstack(&attr, &stack_lo, &stack_size) == 0 && stack_lo != NULL && stack_size != 0;
154+
pthread_attr_destroy(&attr);
155+
if (!ok) return 0;
156+
*lo = (uintptr_t)stack_lo;
157+
*hi = *lo + stack_size;
158+
return 1;
159+
}
160+
#else
161+
static inline int vgc_get_stack_bounds(uintptr_t* lo, uintptr_t* hi) {
162+
(void)lo;
163+
(void)hi;
164+
return 0;
165+
}
166+
#endif
167+
115168
// ============================================================
116169
// Bitmap operations (for mark/alloc bitmaps)
117170
// ============================================================

vlib/builtin/array_d_gcboehm_opt.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ fn (mut a array) ensure_cap_noscan(required int) {
120120
}
121121
}
122122
new_size := u64(cap) * u64(a.element_size)
123-
new_data := vcalloc_noscan(new_size)
123+
new_data := unsafe { malloc_noscan(__at_least_one(new_size)) }
124124
if a.data != unsafe { nil } {
125125
unsafe { vmemcpy(new_data, a.data, u64(a.len) * u64(a.element_size)) }
126126
// TODO: the old data may be leaked when no GC is used (ref-counting?)

0 commit comments

Comments
 (0)