@@ -49,6 +49,8 @@ class RandomNumberGenerator
49
49
const std::uniform_int_distribution<uint32_t > buffSzRange = std::uniform_int_distribution<uint32_t >(minVirtualMemoryBufferSize, maxVirtualMemoryBufferSize);
50
50
};
51
51
52
+ RandomNumberGenerator rng;
53
+
52
54
template <typename AlctrType>
53
55
class AllocatorHandler
54
56
{
@@ -101,38 +103,16 @@ class AllocatorHandler
101
103
const uint32_t multiAllocCnt = rng.getRandomNumber (1u , 500u );
102
104
for (uint32_t i = 0u ; i < multiAllocCnt; i++)
103
105
{
104
- outAddresses.clear ();
105
- sizes.clear ();
106
- alignments.clear ();
107
-
106
+ uint32_t addressesToAllcate = allocDataSoA.randomizeAllocData (alctr, randAllocParams);
108
107
// randomly decide how many allocs in a `multi_alloc` NOTE: must pick number less than `traits::max_multi_alloc`
109
- constexpr uint32_t upperBound = Traits::maxMultiOps;
110
- uint32_t allocCntInMultiAlloc = rng.getRandomNumber (1u , upperBound);
111
-
112
- for (uint32_t j = 0u ; j < allocCntInMultiAlloc; j++)
113
- {
114
- // randomly decide sizes (but always less than `address_allocator_traits::max_size`)
115
- outAddresses.emplace_back (AlctrType::invalid_address);
116
-
117
- if constexpr (std::is_same<AlctrType, core::PoolAddressAllocator<uint32_t >>::value)
118
- {
119
- sizes.emplace_back (randAllocParams.blockSz );
120
- alignments.emplace_back (randAllocParams.blockSz );
121
- }
122
- else
123
- {
124
- sizes.emplace_back (rng.getRandomNumber (1u , std::max (Traits::max_size (alctr), 1u )));
125
- alignments.emplace_back (rng.getRandomNumber (1u , randAllocParams.maxAlign ));
126
- }
127
- }
128
108
129
- Traits::multi_alloc_addr (alctr, allocCntInMultiAlloc, outAddresses.data (), sizes.data (), alignments.data ());
109
+ Traits::multi_alloc_addr (alctr, addressesToAllcate, allocDataSoA. outAddresses .data (), allocDataSoA. sizes .data (), allocDataSoA. alignments .data ());
130
110
131
111
// record all successful alloc addresses to the `core::vector`
132
- for (uint32_t j = 0u ; j < outAddresses .size () ; j++)
112
+ for (uint32_t j = 0u ; j < allocDataSoA .size ; j++)
133
113
{
134
- if (outAddresses[j] != AlctrType::invalid_address)
135
- results.push_back ({ outAddresses[j], sizes[j], alignments[j] });
114
+ if (allocDataSoA. outAddresses [j] != AlctrType::invalid_address)
115
+ results.push_back ({ allocDataSoA. outAddresses [j], allocDataSoA. sizes [j], allocDataSoA. alignments [j] });
136
116
}
137
117
138
118
// run random dealloc function
@@ -178,9 +158,7 @@ class AllocatorHandler
178
158
179
159
for (uint32_t i = 0u ; (i < multiFreeCnt) && results.size (); i++)
180
160
{
181
- outAddresses.clear ();
182
- sizes.clear ();
183
- alignments.clear ();
161
+ allocDataSoA.reset ();
184
162
185
163
// randomly how many addresses we should deallocate (but obvs less than all allocated) NOTE: must pick number less than `traits::max_multi_free`
186
164
const uint32_t addressesToFreeUpperBound = min (Traits::maxMultiOps, results.size ());
@@ -190,11 +168,10 @@ class AllocatorHandler
190
168
for (uint32_t j = 0u ; j < addressesToFreeCnt; j++)
191
169
{
192
170
it--;
193
- outAddresses.push_back (it->outAddr );
194
- sizes.push_back (it->size );
171
+ allocDataSoA.addElement (*it);
195
172
}
196
173
197
- Traits::multi_free_addr (alctr, addressesToFreeCnt, outAddresses.data (), sizes.data ());
174
+ Traits::multi_free_addr (alctr, addressesToFreeCnt, allocDataSoA. outAddresses .data (), allocDataSoA. sizes .data ());
198
175
results.erase (results.end () - addressesToFreeCnt, results.end ());
199
176
}
200
177
}
@@ -216,13 +193,62 @@ class AllocatorHandler
216
193
}
217
194
218
195
private:
219
- RandomNumberGenerator rng;
220
196
core::vector<AllocationData> results;
221
197
222
198
// these hold inputs for `multi_alloc_addr` and `multi_free_addr`
223
- core::vector<uint32_t > outAddresses;
224
- core::vector<uint32_t > sizes;
225
- core::vector<uint32_t > alignments;
199
+
200
+ struct AllocationDataSoA
201
+ {
202
+ uint32_t randomizeAllocData (AlctrType& alctr, RandParams& randAllocParams)
203
+ {
204
+ constexpr uint32_t upperBound = Traits::maxMultiOps - 1u ;
205
+ uint32_t allocCntInMultiAlloc = rng.getRandomNumber (1u , upperBound);
206
+
207
+ std::fill (outAddresses.begin (), outAddresses.begin () + allocCntInMultiAlloc, AlctrType::invalid_address);
208
+
209
+ for (uint32_t j = 0u ; j < allocCntInMultiAlloc; j++)
210
+ {
211
+ // randomly decide sizes (but always less than `address_allocator_traits::max_size`)
212
+
213
+ if constexpr (std::is_same<AlctrType, core::PoolAddressAllocator<uint32_t >>::value)
214
+ {
215
+ sizes[j] = randAllocParams.blockSz ;
216
+ alignments[j] = randAllocParams.blockSz ;
217
+ }
218
+ else
219
+ {
220
+ sizes[j] = rng.getRandomNumber (1u , std::max (Traits::max_size (alctr), 1u ));
221
+ alignments[j] = rng.getRandomNumber (1u , randAllocParams.maxAlign );
222
+ }
223
+ }
224
+
225
+ size = allocCntInMultiAlloc;
226
+
227
+ return allocCntInMultiAlloc;
228
+ }
229
+
230
+ void addElement (const AllocationData& allocData)
231
+ {
232
+ outAddresses[end] = allocData.outAddr ;
233
+ sizes[end] = allocData.size ;
234
+ end++;
235
+ _NBL_DEBUG_BREAK_IF (end > Traits::maxMultiOps);
236
+ }
237
+
238
+ inline void reset () { end = 0u ; }
239
+
240
+ union
241
+ {
242
+ uint32_t end = 0u ;
243
+ uint32_t size;
244
+ };
245
+
246
+ core::vector<uint32_t > outAddresses = core::vector<uint32_t >(Traits::maxMultiOps, AlctrType::invalid_address);
247
+ core::vector<uint32_t > sizes = core::vector<uint32_t >(Traits::maxMultiOps, 0u );
248
+ core::vector<uint32_t > alignments = core::vector<uint32_t >(Traits::maxMultiOps, 0u );
249
+ };
250
+
251
+ AllocationDataSoA allocDataSoA;
226
252
};
227
253
228
254
template <>
0 commit comments