1 | #include <iostream> |
2 | #include <cstring> |
3 | #include <thread> |
4 | #include <pcg_random.hpp> |
5 | #include <Common/ArrayCache.h> |
6 | #include <IO/ReadHelpers.h> |
7 | |
8 | |
9 | template <typename Cache> |
10 | void printStats(const Cache & cache) |
11 | { |
12 | typename Cache::Statistics statistics = cache.getStatistics(); |
13 | std::cerr |
14 | << "total_chunks_size: " << statistics.total_chunks_size << "\n" |
15 | << "total_allocated_size: " << statistics.total_allocated_size << "\n" |
16 | << "total_size_currently_initialized: " << statistics.total_size_currently_initialized << "\n" |
17 | << "total_size_in_use: " << statistics.total_size_in_use << "\n" |
18 | << "num_chunks: " << statistics.num_chunks << "\n" |
19 | << "num_regions: " << statistics.num_regions << "\n" |
20 | << "num_free_regions: " << statistics.num_free_regions << "\n" |
21 | << "num_regions_in_use: " << statistics.num_regions_in_use << "\n" |
22 | << "num_keyed_regions: " << statistics.num_keyed_regions << "\n" |
23 | << "hits: " << statistics.hits << "\n" |
24 | << "concurrent_hits: " << statistics.concurrent_hits << "\n" |
25 | << "misses: " << statistics.misses << "\n" |
26 | << "allocations: " << statistics.allocations << "\n" |
27 | << "allocated_bytes: " << statistics.allocated_bytes << "\n" |
28 | << "evictions: " << statistics.evictions << "\n" |
29 | << "evicted_bytes: " << statistics.evicted_bytes << "\n" |
30 | << "secondary_evictions: " << statistics.secondary_evictions << "\n" |
31 | << "\n" ; |
32 | } |
33 | |
34 | /** Example: |
35 | * time ./array_cache 68000000 1 10000000 2000000 200 |
36 | */ |
37 | |
38 | |
39 | int main(int argc, char ** argv) |
40 | { |
41 | if (argc < 6) |
42 | { |
43 | std::cerr << "Usage: program cache_size num_threads num_iterations region_max_size max_key\n" ; |
44 | return 1; |
45 | } |
46 | |
47 | size_t cache_size = DB::parse<size_t>(argv[1]); |
48 | size_t num_threads = DB::parse<size_t>(argv[2]); |
49 | size_t num_iterations = DB::parse<size_t>(argv[3]); |
50 | size_t region_max_size = DB::parse<size_t>(argv[4]); |
51 | size_t max_key = DB::parse<size_t>(argv[5]); |
52 | |
53 | using Cache = ArrayCache<int, int>; |
54 | Cache cache(cache_size); |
55 | |
56 | std::vector<std::thread> threads; |
57 | for (size_t i = 0; i < num_threads; ++i) |
58 | { |
59 | threads.emplace_back([&] |
60 | { |
61 | pcg64 generator(randomSeed()); |
62 | |
63 | for (size_t j = 0; j < num_iterations; ++j) |
64 | { |
65 | size_t size = std::uniform_int_distribution<size_t>(1, region_max_size)(generator); |
66 | int key = std::uniform_int_distribution<int>(1, max_key)(generator); |
67 | |
68 | cache.getOrSet( |
69 | key, |
70 | [=]{ return size; }, |
71 | [=](void * /*ptr*/, int & payload) |
72 | { |
73 | payload = j; |
74 | // memset(ptr, j, size); |
75 | }, |
76 | nullptr); |
77 | |
78 | // printStats(cache); |
79 | } |
80 | }); |
81 | } |
82 | |
83 | std::atomic_bool stop{}; |
84 | |
85 | std::thread stats_thread([&] |
86 | { |
87 | while (!stop) |
88 | { |
89 | usleep(100000); |
90 | printStats(cache); |
91 | } |
92 | }); |
93 | |
94 | for (auto & thread : threads) |
95 | thread.join(); |
96 | |
97 | stop = true; |
98 | stats_thread.join(); |
99 | |
100 | return 0; |
101 | |
102 | /* |
103 | using Cache = ArrayCache<int, int>; |
104 | Cache cache(64 * 1024 * 1024); |
105 | |
106 | cache.getOrSet( |
107 | 1, |
108 | [=]{ return 32 * 1024 * 1024; }, |
109 | [=](void * ptr, int & payload) |
110 | { |
111 | payload = 1; |
112 | }, |
113 | nullptr); |
114 | |
115 | printStats(cache); |
116 | |
117 | cache.getOrSet( |
118 | 2, |
119 | [=]{ return 32 * 1024 * 1024; }, |
120 | [=](void * ptr, int & payload) |
121 | { |
122 | payload = 2; |
123 | }, |
124 | nullptr); |
125 | |
126 | printStats(cache); |
127 | |
128 | cache.getOrSet( |
129 | 3, |
130 | [=]{ return 32 * 1024 * 1024; }, |
131 | [=](void * ptr, int & payload) |
132 | { |
133 | payload = 3; |
134 | }, |
135 | nullptr); |
136 | |
137 | printStats(cache);*/ |
138 | } |
139 | |