-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfast.cpp
105 lines (88 loc) · 2.53 KB
/
fast.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
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
#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
#include <cstring>
#include <chrono>
using namespace std;
using namespace chrono;
int NUM_THREADS = 4;
void readBlock(const char *fileName, int threadId, int blockSize, vector<int> &result)
{
ifstream inFile(fileName, ios::binary);
if (!inFile.is_open())
{
cerr << "Error opening file for reading." << endl;
return;
}
inFile.seekg(threadId * blockSize, ios::beg);
char buffer[blockSize];
int *intBuffer = reinterpret_cast<int *>(buffer);
while (inFile)
{
inFile.read(buffer, blockSize);
long long bytesRead = static_cast<long long>(inFile.gcount());
for (long long i = 0; i < bytesRead / sizeof(int); ++i)
{
result[threadId] ^= intBuffer[i];
}
inFile.seekg((NUM_THREADS - 1) * blockSize, ios::cur);
}
inFile.close();
}
int clearCache()
{
// Clear the file system cache by dropping caches
return system("sudo sh -c \"/usr/bin/echo 3 > /proc/sys/vm/drop_caches\"");
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
cerr << "Usage: ./fast <file_to_read>" << endl;
return 1;
}
const char *fileName = argv[1];
ifstream inFile(fileName, ios::binary | ios::ate);
if (!inFile.is_open())
{
cerr << "Error opening file for reading." << endl;
return 1;
}
size_t fileSize = static_cast<size_t>(inFile.tellg());
inFile.close();
// vector<int> blockSizes = {128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304};
vector<int> blockSizes = {1048576};
cout << "Block Size \t\tXOR \t\tDuration" << endl;
for (auto blockSize : blockSizes)
{
int res = clearCache();
// The no. of blocks that each thread will run
long long numBlocks = fileSize / (NUM_THREADS * blockSize);
vector<int> result(NUM_THREADS, 0); // Results from threads
vector<thread> threads;
auto start = high_resolution_clock::now();
for (int i = 0; i < NUM_THREADS; ++i)
{
threads.emplace_back(readBlock, fileName, i, blockSize, ref(result));
// emplace_back is better when using a vector of threads
}
// Wait for all threads to finish
for (thread &t : threads)
{
t.join();
}
// Calculate the final XOR result
int finalResult = result[0];
for (int i = 1; i < result.size(); ++i)
{
finalResult ^= result[i];
}
auto stop = high_resolution_clock::now();
int duration = duration_cast<seconds>(stop - start).count();
// Print the result
// cout << blockSize << "\t\t" << (finalResult) << endl;
printf("%d \t\t\t%08x\t\t%d \n", blockSize, finalResult, duration);
}
return 0;
}