-
Notifications
You must be signed in to change notification settings - Fork 27
/
smmalloc_test_impl.inl
140 lines (108 loc) · 3.72 KB
/
smmalloc_test_impl.inl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
void TEST_THREADENTRY(HEAP heap, size_t* randomSizes, size_t sizesCount, TestResult* result, uint32_t /*threadIndex*/)
{
(void)heap;
PerfTestGlobals& globals = PerfTestGlobals::get();
std::vector<void*> ptrsStorage;
ptrsStorage.resize(PerfTestGlobals::kAllocationsCount);
memset(&ptrsStorage[0], 0, sizeof(void*) * ptrsStorage.size());
/*
#ifdef _WIN32
HANDLE thread = GetCurrentThread();
SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL);
SetThreadIdealProcessor(thread, threadIndex);
#endif
*/
ON_THREAD_START;
// spin wait
while (globals.canStart.load() == 0)
{
}
auto begin = std::chrono::steady_clock::now();
uint64_t opCount = 0;
uint32_t idx = 0;
uint8_t pattern = 0;
for (size_t i = 0; i < PerfTestGlobals::kAllocationsCount; i++)
{
size_t bytesCount = randomSizes[idx % sizesCount];
ptrsStorage[i] = MALLOC(bytesCount, 16);
// memset(ptrsStorage[i], pattern, bytesCount);
opCount++;
idx++;
pattern++;
}
const int iterationsCount = 300;
for (int iteration = 0; iteration < iterationsCount; iteration++)
{
for (size_t i = 0; i < PerfTestGlobals::kAllocationsCount; i++)
{
FREE(ptrsStorage[i]);
opCount++;
size_t bytesCount = randomSizes[idx % sizesCount];
ptrsStorage[i] = MALLOC(bytesCount, 16);
// memset(ptrsStorage[i], pattern, bytesCount);
pattern++;
opCount++;
idx++;
}
}
for (size_t i = 0; i < PerfTestGlobals::kAllocationsCount; i++)
{
FREE(ptrsStorage[i]);
opCount++;
}
auto end = std::chrono::steady_clock::now();
auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin);
long long ms = elapsedTime.count();
result->opCount = opCount;
result->timeMs = ms;
ON_THREAD_FINISHED;
}
void TEST_ENTRYPOINT()
{
PerfTestGlobals& globals = PerfTestGlobals::get();
globals.canStart.store(0);
HEAP heap = CREATE_HEAP;
std::vector<std::thread> threads;
threads.reserve(PerfTestGlobals::kThreadsCount);
std::vector<TestResult> results;
results.resize(PerfTestGlobals::kThreadsCount);
// create threads
for (uint32_t i = 0; i < PerfTestGlobals::kThreadsCount; i++)
{
threads.push_back(
std::thread(TEST_THREADENTRY, heap, globals.randomSequence.data(), globals.randomSequence.size(), &results[i], i));
}
// sleep for 2 seconds (just in case)
std::this_thread::sleep_for(std::chrono::seconds(2));
// run
globals.canStart.store(1);
for (auto& t : threads)
{
t.join();
}
globals.canStart.store(0);
std::vector<double> opsSec;
opsSec.resize(PerfTestGlobals::kThreadsCount);
for (uint32_t i = 0; i < PerfTestGlobals::kThreadsCount; i++)
{
opsSec[i] = results[i].opCount * 1000.0 / results[i].timeMs;
}
double timeMin = FLT_MAX;
double timeMax = -FLT_MAX;
double opsMin = FLT_MAX;
double opsMax = -FLT_MAX;
double opsAverage = 0.0f;
for (uint32_t i = 0; i < PerfTestGlobals::kThreadsCount; i++)
{
double opsPerSec = opsSec[i];
opsAverage += opsPerSec;
opsMin = std::min(opsMin, opsPerSec);
opsMax = std::max(opsMax, opsPerSec);
timeMin = std::min(results[i].timeMs / 1000.0, timeMin);
timeMax = std::max(results[i].timeMs / 1000.0, timeMax);
}
opsAverage /= (double)PerfTestGlobals::kThreadsCount;
const char* s = STRINGIFY(ALLOCATOR_TEST_NAME);
printf("%s\t%d\t%3.0f\t%3.0f\t%3.0f\t%3.2f\t%3.2f\n", s, PerfTestGlobals::kThreadsCount, opsMin, opsMax, opsAverage, timeMin, timeMax);
DESTROY_HEAP;
}