-
Notifications
You must be signed in to change notification settings - Fork 160
/
misaligned-access.cpp
69 lines (55 loc) · 1.51 KB
/
misaligned-access.cpp
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
#include <chrono>
#include <iostream>
#include <vector>
#include <cstdint>
#include <cassert>
#define CACHE_LINE_SIZE 64
#ifndef REPETITIONS
#define REPETITIONS 100 * 1024 * 1024
#endif
using Type = uint32_t;
void test_memory(std::vector<Type*>& memory)
{
using Clock = std::chrono::steady_clock;
size_t size = memory.size();
auto start = Clock::now();
for (int i = 0; i < REPETITIONS; i++)
{
for (size_t j = 0; j < size; j++)
{
*memory[j] += j;
}
}
std::cerr << std::chrono::duration_cast<std::chrono::milliseconds>(Clock::now() - start).count() << std::endl;
}
int main(int argc, char** argv)
{
if (argc < 2)
{
std::cout << "Usage: misaligned-access <offset>" << std::endl;
return 1;
}
int offset = std::stoi(argv[1]);
Type* memory;
// allocated two cache lines
size_t size = CACHE_LINE_SIZE * 2;
#ifdef _MSC_VER
memory = _aligned_malloc(size, CACHE_LINE_SIZE);
#else
if (posix_memalign((void**) &memory, CACHE_LINE_SIZE, size))
{
std::cerr << "Couldn't allocate memory" << std::endl;
return 1;
}
#endif
assert((reinterpret_cast<uintptr_t>(memory) & 63) == 0);
// pointer is kept in vector to prevent the compiler from optimizing the writes to a register
std::vector<Type*> pointers(1, reinterpret_cast<Type*>(reinterpret_cast<char*>(memory) + offset));
test_memory(pointers);
#ifdef _MSC_VER
_aligned_free(memory);
#else
free(memory);
#endif
return 0;
}