File tree 4 files changed +108
-1
lines changed
4 files changed +108
-1
lines changed Original file line number Diff line number Diff line change 1
1
# libglaswegian
2
- Use GHC's Memory Allocator from C
2
+
3
+ Use GHC's Memory Allocator from C/C++. Yes, I'm serious. You can do this:
4
+
5
+ ``` c++
6
+ #include < iostream>
7
+ #include < vector>
8
+
9
+ #include < glaswegian++.h>
10
+
11
+ #define LEN 4096
12
+
13
+ int main ()
14
+ {
15
+ ghc_init ();
16
+ std::vector<double, GlaswegianAllocator<double >> xs;
17
+ for(int i = 0; i < LEN; i++)
18
+ {
19
+ xs.emplace_back(i * i);
20
+ }
21
+ double s = 0;
22
+ for(double i : xs)
23
+ {
24
+ s += i;
25
+ }
26
+ std::cout << s << std::endl;
27
+ return 0;
28
+ }
29
+ ```
30
+
31
+ This works by allocating pinned ` MutableByteArray# ` s, then sticking a
32
+ ` StablePtr ` into a radix tree with the ` MutableByteArray# ` 's address as the key.
33
+ This keeps the array alive on the heap until the caller frees the memory (which
34
+ just deletes the ` StablePtr ` from the tree and does ` freeStablePtr ` ).
35
+
36
+ A further optimization might be to call the RTS' C functions for doing
37
+ allocations directly, but this library is * shockingly* competitive with other
38
+ memory allocators. I'll add benchmarks soon.
39
+
40
+ This library is a fun toy I made for some silly benchmarks I wanted to run. It
41
+ is probably only useful for getting your colleagues to shut up about how
42
+ "garbage collectors are slow."
Original file line number Diff line number Diff line change
1
+ #include < limits>
2
+
3
+ extern " C"
4
+ {
5
+ #include < glaswegian.h>
6
+ };
7
+
8
+ // Call ghc_init before constructing one of these.
9
+ template <typename a>
10
+ struct GlaswegianAllocator
11
+ {
12
+ typedef a value_type;
13
+
14
+ GlaswegianAllocator () = default ;
15
+
16
+ a* allocate (std::size_t n)
17
+ {
18
+ if (n > std::numeric_limits<std::size_t >::max () / sizeof (a))
19
+ {
20
+ throw std::bad_alloc ();
21
+ }
22
+ if (auto p = static_cast <a*>(ghc_alloc (n*sizeof (a))))
23
+ {
24
+ return p;
25
+ }
26
+ throw std::bad_alloc ();
27
+ }
28
+ void deallocate (a* p, std::size_t ) noexcept
29
+ {
30
+ ghc_free (p);
31
+ }
32
+ };
33
+
34
+ template <typename a, typename b>
35
+ bool operator ==(const GlaswegianAllocator<a>&, const GlaswegianAllocator<b>&)
36
+ {
37
+ return true ;
38
+ }
39
+ template <typename a, typename b>
40
+ bool operator !=(const GlaswegianAllocator<a>&, const GlaswegianAllocator<b>&)
41
+ {
42
+ return false ;
43
+ }
Original file line number Diff line number Diff line change @@ -27,6 +27,7 @@ foreign-library glaswegian
27
27
cbits/ghc_cleanup.c
28
28
include-dirs : include
29
29
install-includes : glaswegian.h
30
+ glaswegian++.h
30
31
ghc-options : -O2
31
32
-threaded
32
33
-Wall
Original file line number Diff line number Diff line change
1
+ #include < iostream>
2
+ #include < vector>
3
+
4
+ #include < glaswegian++.h>
5
+
6
+ #define LEN 4096
7
+
8
+ int main ()
9
+ {
10
+ ghc_init ();
11
+ std::vector<double , GlaswegianAllocator<double >> xs;
12
+ for (int i = 0 ; i < LEN; i++)
13
+ {
14
+ xs.emplace_back (i * i);
15
+ }
16
+ double s = 0 ;
17
+ for (double i : xs)
18
+ {
19
+ s += i;
20
+ }
21
+ std::cout << s << std::endl;
22
+ return 0 ;
23
+ }
You can’t perform that action at this time.
0 commit comments