/home/liu/actions-runner/_work/ccv/ccv/test/unit/memory.tests.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "ccv.h" |
2 | | #include "ccv_internal.h" |
3 | | #include "case.h" |
4 | | |
5 | | uint64_t uniqid() |
6 | 800k | { |
7 | 800k | union { |
8 | 800k | uint64_t u; |
9 | 800k | uint8_t chr[8]; |
10 | 800k | } sign; |
11 | 800k | int i; |
12 | 7.20M | for (i = 0; i < 8; i++6.40M ) |
13 | 6.40M | sign.chr[i] = rand() & 0xff; |
14 | 800k | return sign.u; |
15 | 800k | } |
16 | | |
17 | 8.65M | #define N (800000) |
18 | | |
19 | | TEST_CASE("random cache put/delete/get") |
20 | 1 | { |
21 | 1 | ccv_cache_t cache; |
22 | 1 | ccv_cache_init(&cache, N, 1, ccfree); |
23 | 1 | uint64_t* sigs = ccmalloc(sizeof(uint64_t) * N); |
24 | 1 | void** mems = ccmalloc(sizeof(void*) * N); |
25 | 1 | int i; |
26 | 800k | for (i = 0; i < N; i++800k ) |
27 | 800k | { |
28 | 800k | sigs[i] = uniqid(); |
29 | 800k | mems[i] = ccmalloc(1); |
30 | 800k | ccv_cache_put(&cache, sigs[i], mems[i], 1, 0); |
31 | 800k | REQUIRE_EQ(i + 1, cache.size, "at %d should has cache size %d", i, i); |
32 | 800k | } |
33 | 1 | uint8_t deleted[N]; |
34 | 800k | for (i = 0; i < N; i++800k ) |
35 | 800k | { |
36 | 800k | deleted[i] = 1; |
37 | 800k | if (deleted[i]) |
38 | 800k | ccv_cache_delete(&cache, sigs[i]); |
39 | 800k | REQUIRE_EQ(N - 1 - i, cache.size, "at %d should has cache size %d", i, 0 N0 - 1 - i); |
40 | 800k | } |
41 | 800k | for (i = 0; 1 i < N; i++800k ) |
42 | 800k | { |
43 | 800k | deleted[i] = (rand() % 3 == 0); |
44 | 800k | if (!deleted[i]) |
45 | 534k | { |
46 | 534k | mems[i] = ccmalloc(1); |
47 | 534k | ccv_cache_put(&cache, sigs[i], mems[i], 1, 0); |
48 | 534k | } |
49 | 800k | } |
50 | 800k | for (i = 0; i < N; i++800k ) |
51 | 800k | { |
52 | 800k | deleted[i] = (rand() % 3 == 0); |
53 | 800k | if (deleted[i]) |
54 | 266k | ccv_cache_delete(&cache, sigs[i]); |
55 | 533k | else { |
56 | 533k | mems[i] = ccmalloc(1); |
57 | 533k | ccv_cache_put(&cache, sigs[i], mems[i], 1, 0); |
58 | 533k | } |
59 | 800k | } |
60 | 800k | for (i = 0; i < N; i++800k ) |
61 | 800k | { |
62 | 800k | void* x = ccv_cache_get(&cache, sigs[i], 0); |
63 | 800k | if (!deleted[i] && x533k ) // x may be pull off the cache |
64 | 533k | { |
65 | 533k | REQUIRE_EQ((uint64_t)mems[i], (uint64_t)x, "value at %d should be consistent", i); |
66 | 533k | } else |
67 | 800k | REQUIRE_EQ266k (0, (uint64_t)x, "at %d should not exist", i); |
68 | 800k | } |
69 | 1 | ccv_cache_close(&cache); |
70 | 1 | ccfree(mems); |
71 | 1 | ccfree(sigs); |
72 | 1 | } |
73 | | |
74 | | TEST_CASE("garbage collector 95\% hit rate") |
75 | 1 | { |
76 | 1 | int i; |
77 | | // deliberately let only cache size fits 90% of data |
78 | 1 | ccv_enable_cache(ccv_compute_dense_matrix_size(1, 1, CCV_32S | CCV_C1) * N * 9 / 10); |
79 | 800k | for (i = 0; i < N; i++800k ) |
80 | 800k | { |
81 | 800k | ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, 0); |
82 | 800k | dmt->data.i32[0] = i; |
83 | 800k | dmt->sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN); |
84 | 800k | dmt->type |= CCV_REUSABLE; |
85 | 800k | ccv_matrix_free(dmt); |
86 | 800k | } |
87 | 1 | int percent = 0, total = 0; |
88 | 752k | for (i = N1 - 1; i > N * 6 / 100; i--751k ) |
89 | 751k | { |
90 | 751k | uint64_t sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN); |
91 | 751k | ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, sig); |
92 | 751k | if (i == dmt->data.i32[0]) |
93 | 720k | ++percent; |
94 | 751k | ++total; |
95 | 751k | ccv_matrix_free_immediately(dmt); |
96 | 751k | } |
97 | 1 | REQUIRE((double)percent / (double)total > 0.95, "the cache hit (%lf) should be greater than 95%%", (double)percent / (double)total); |
98 | 1 | ccv_disable_cache(); |
99 | 1 | } |
100 | | |
101 | | TEST_CASE("garbage collector 47\% hit rate") |
102 | 1 | { |
103 | 1 | int i; |
104 | | // deliberately let only cache size fits 45% of data |
105 | 1 | ccv_enable_cache((size_t)((int64_t)ccv_compute_dense_matrix_size(1, 1, CCV_32S | CCV_C1) * N * 45 / 100)); |
106 | 800k | for (i = 0; i < N; i++800k ) |
107 | 800k | { |
108 | 800k | ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, 0); |
109 | 800k | dmt->data.i32[0] = i; |
110 | 800k | dmt->sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN); |
111 | 800k | dmt->type |= CCV_REUSABLE; |
112 | 800k | ccv_matrix_free(dmt); |
113 | 800k | } |
114 | 1 | int percent = 0, total = 0; |
115 | 752k | for (i = N1 - 1; i > N * 6 / 100; i--751k ) |
116 | 751k | { |
117 | 751k | uint64_t sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN); |
118 | 751k | ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, sig); |
119 | 751k | if (i == dmt->data.i32[0]) |
120 | 360k | ++percent; |
121 | 751k | ++total; |
122 | 751k | ccv_matrix_free_immediately(dmt); |
123 | 751k | } |
124 | 1 | REQUIRE((double)percent / (double)total > 0.47, "the cache hit (%lf) should be greater than 47%%", (double)percent / (double)total); |
125 | 1 | ccv_disable_cache(); |
126 | 1 | } |
127 | | |
128 | | TEST_CASE("multi-type garbage collector 92\% hit rate") |
129 | 1 | { |
130 | 1 | int i; |
131 | 1 | ccv_enable_cache((ccv_compute_dense_matrix_size(1, 1, CCV_32S | CCV_C1) + (sizeof(ccv_array_t) + 4 * 4)) * N * 9 / 10); |
132 | 800k | for (i = 0; i < N; i++800k ) |
133 | 800k | { |
134 | 800k | ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, 0); |
135 | 800k | dmt->data.i32[0] = i; |
136 | 800k | dmt->sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN); |
137 | 800k | dmt->type |= CCV_REUSABLE; |
138 | 800k | ccv_matrix_free(dmt); |
139 | 800k | ccv_array_t* array = ccv_array_new(4, 4, 0); |
140 | 800k | int j = i; |
141 | 800k | ccv_array_push(array, &j); |
142 | 800k | j = 0; |
143 | 800k | ccv_array_push(array, &j); |
144 | 800k | j = ~i; |
145 | 800k | ccv_array_push(array, &j); |
146 | 800k | j = -i; |
147 | 800k | ccv_array_push(array, &j); |
148 | 800k | array->sig = ccv_cache_generate_signature((const char*)&j, 4, CCV_EOF_SIGN); |
149 | 800k | array->type |= CCV_REUSABLE; |
150 | 800k | ccv_array_free(array); |
151 | 800k | } |
152 | 1 | int percent = 0, total = 0; |
153 | 752k | for (i = N1 - 1; i > N * 6 / 100; i--751k ) |
154 | 751k | { |
155 | 751k | uint64_t sig = ccv_cache_generate_signature((const char*)&i, 4, CCV_EOF_SIGN); |
156 | 751k | ccv_dense_matrix_t* dmt = ccv_dense_matrix_new(1, 1, CCV_32S | CCV_C1, 0, sig); |
157 | 751k | if (i == dmt->data.i32[0]) |
158 | 720k | ++percent; |
159 | 751k | ++total; |
160 | 751k | ccv_matrix_free_immediately(dmt); |
161 | 751k | int j = -i; |
162 | 751k | sig = ccv_cache_generate_signature((const char*)&j, 4, CCV_EOF_SIGN); |
163 | 751k | ccv_array_t* array = ccv_array_new(4, 4, sig); |
164 | 751k | if (i == *(int*)ccv_array_get(array, 0) && |
165 | 751k | 0 == *(int*)720k ccv_array_get720k (array, 1) && |
166 | 751k | ~i == *(int*)720k ccv_array_get720k (array, 2) && |
167 | 751k | -i == *(int*)720k ccv_array_get720k (array, 3)) |
168 | 720k | ++percent; |
169 | 751k | ++total; |
170 | 751k | ccv_array_free_immediately(array); |
171 | 751k | } |
172 | 1 | REQUIRE((double)percent / (double)total > 0.92, "the cache hit (%lf) should be greater than 92%%", (double)percent / (double)total); |
173 | 1 | ccv_disable_cache(); |
174 | 1 | } |
175 | | |
176 | | #include "case_main.h" |