-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOwnSimulation.cpp
More file actions
132 lines (125 loc) · 4.9 KB
/
OwnSimulation.cpp
File metadata and controls
132 lines (125 loc) · 4.9 KB
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
//
// Created by Nick Chapman on 4/19/17.
//
#include "OwnSimulation.h"
OwnSimulation::OwnSimulation() {
this->mt = std::mt19937(std::random_device{}());
this->dist = std::uniform_int_distribution<unsigned int>(0, UINT32_MAX);
}
OwnSimulation::OwnSimulation(unsigned int nFrames, bool verbose) : PagingSimulation(nFrames, verbose) {
this->mt = std::mt19937(std::random_device{}());
this->dist = std::uniform_int_distribution<unsigned int>(0, UINT32_MAX);
}
void OwnSimulation::UpdateEntry(PageTableEntry* entry) {
this->mSinceLastHit = 0;
auto it = this->cacheMap.at(entry->mVpn);
this->cacheList.splice(this->cacheList.begin(), this->cacheList, it);
}
PageTableEntry* OwnSimulation::RemoveFrameEntry() {
this->mSinceLastHit += 1;
PageTableEntry* removed;
if (this->mSinceLastHit > this->mFrames.size() || this->mRandomReplacementsRemaining) {
// We are at risk of trashing so we will replace at random
// Check if we are just starting this
if (this->mRandomReplacementsRemaining == 0) {
// We are just starting our thrashing prevention so allocate a block of random replacements
this->mRandomReplacementsRemaining = this->mNFrames;
}
else {
// We are in the middle of thrashing prevention so use one of our random replacements
this->mRandomReplacementsRemaining -= 1;
}
unsigned long advance = this->dist(this->mt) % this->mFrames.size();
auto it = this->mFrames.begin();
std::advance(it, advance);
removed = it->second;
// Need to remove it from the cache
auto cachePosition = this->cacheMap.at(removed->mVpn);
this->cacheList.erase(cachePosition);
this->cacheMap.erase(removed->mVpn);
this->mFrames.erase(removed->mVpn);
}
else {
removed = this->cacheList.back();
this->cacheList.pop_back();
this->cacheMap.erase(removed->mVpn);
this->mFrames.erase(removed->mVpn);
}
return removed;
}
void OwnSimulation::AddFrameEntry(PageTableEntry* entry) {
this->cacheList.push_front(entry);
this->cacheMap.emplace(entry->mVpn, this->cacheList.begin());
this->mFrames.emplace(entry->mVpn, entry);
}
void OwnSimulation::Process() {
unsigned int accesses = 0;
unsigned int misses = 0;
unsigned int writes = 0;
unsigned int drops = 0;
// Read in all of the memory accesses and process them accordingly
unsigned int address;
char action;
while (std::cin >> std::hex >> address >> action) {
PageTableEntry* entry;
accesses += 1;
// Calculate the VPN
unsigned int vpn = address / this->cPageSize;
// Check if the page is in the frames
if (this->mFrames.count(vpn) == 1) {
entry = this->mFrames.at(vpn);
this->UpdateEntry(entry);
// It's in the frames and it's a hit!
// If it's a write then this dirties the page
if (action == 'W') {
entry->mDirty = true;
}
else {
// Since it's just reading we can continue
continue;
}
}
else {
// It's a miss
misses += 1;
entry = new PageTableEntry(vpn);
// Check if our frames are full yet
PageTableEntry* removed = nullptr;
if (this->mFrames.size() >= this->mNFrames) {
// It's full so remove one
removed = this->RemoveFrameEntry();
// Put the removed one back into the general page table
// Put the new one into the frames
this->AddFrameEntry(entry);
// Check if we had to write
if (removed->mDirty) {
removed->mDirty = false;
if (this->verbose) {
std::cout << "Page 0x" << std::hex << removed->mVpn << " swaps page 0x" << vpn << std::endl;
}
writes += 1;
}
else {
if (this->verbose) {
std::cout << "Page 0x" << std::hex << removed->mVpn << " overwrites page 0x" << vpn
<< std::endl;
}
drops += 1;
}
}
else {
// The frames aren't full yet
this->AddFrameEntry(entry);
}
// Finally check whether we have dirtied the page we just brought in
if (action == 'W') {
entry->mDirty = true;
}
}
}
// Print out the results of processing the file
std::cout << "Number of memory accesses: " << accesses << std::endl;
std::cout << "Number of misses: " << misses << std::endl;
std::cout << "Number of writes: " << writes << std::endl;
std::cout << "Number of drops: " << drops << std::endl;
}