1
1
#include < litterer/litterer.h>
2
+ #include < numeric>
2
3
3
4
#if _WIN32
4
5
#ifndef NOMINMAX
@@ -49,6 +50,12 @@ void partial_shuffle(std::vector<T>& v, std::size_t n, Generator& g) {
49
50
std::swap (v[i], v[j]);
50
51
}
51
52
}
53
+
54
+ std::vector<size_t > cumulative_sum (const std::vector<size_t >& bins) {
55
+ std::vector<size_t > cumsum (bins.size ());
56
+ std::partial_sum (bins.begin (), bins.end (), cumsum.begin ());
57
+ return cumsum;
58
+ }
52
59
} // namespace
53
60
54
61
void runLitterer () {
@@ -112,8 +119,9 @@ void runLitterer() {
112
119
const std::string mallocSourceObject = mallocInfo.dli_fname ;
113
120
#endif
114
121
115
- const std::size_t nAllocations = data[" NAllocations" ].get <std::size_t >();
116
- const std::size_t maxLiveAllocations = data[" MaxLiveAllocations" ].get <std::size_t >();
122
+ const auto bins = data[" Bins" ].get <std::vector<std::size_t >>();
123
+ const auto nAllocations = data[" NAllocations" ].get <std::size_t >();
124
+ const auto maxLiveAllocations = data[" MaxLiveAllocations" ].get <std::size_t >();
117
125
const std::size_t nAllocationsLitter = maxLiveAllocations * multiplier;
118
126
119
127
fprintf (log , " ==================================== Litterer ====================================\n " );
@@ -126,32 +134,21 @@ void runLitterer() {
126
134
fprintf (log , " timestamp : %s %s\n " , __DATE__, __TIME__);
127
135
fprintf (log , " ==================================================================================\n " );
128
136
129
- assertOrExit (
130
- [&] {
131
- std::size_t sum = 0 ;
132
- for (const auto & bin : data[" Bins" ]) {
133
- sum += bin.get <std::size_t >();
134
- }
135
- return sum;
136
- }() == nAllocations,
137
- log , " The sum of all bins should equal nAllocations." );
137
+ assert (std::accumulate (bins.begin (), bins.end (), 0zu) == nAllocations);
138
+ const std::vector<std::size_t > binsCumSum = cumulative_sum (bins);
138
139
139
140
const auto litterStart = std::chrono::high_resolution_clock::now ();
140
141
141
- std::uniform_int_distribution<std::size_t > distribution (0 , nAllocations - 1 );
142
+ std::uniform_int_distribution<std::int64_t > distribution (1 , nAllocations);
142
143
std::vector<void *> objects = *(new std::vector<void *>);
143
144
objects.reserve (nAllocationsLitter);
144
145
145
146
for (std::size_t i = 0 ; i < nAllocationsLitter; ++i) {
146
- std::size_t allocationSize = 1 ;
147
- std::int64_t offset = static_cast <int64_t >(distribution (generator)) - data[" Bins" ][0 ].get <std::size_t >();
148
-
149
- while (offset >= 0 ) {
150
- ++allocationSize;
151
- offset -= static_cast <std::size_t >(data[" Bins" ][allocationSize - 1 ].get <std::size_t >());
152
- }
153
-
154
- void * pointer = MALLOC (allocationSize);
147
+ const auto offset = distribution (generator);
148
+ const auto it = std::lower_bound (binsCumSum.begin (), binsCumSum.end (), offset);
149
+ assert (it != binsCumSum.end ());
150
+ const auto bin = std::distance (binsCumSum.begin (), it) + 1 ;
151
+ void * pointer = MALLOC (bin);
155
152
objects.push_back (pointer);
156
153
}
157
154
0 commit comments