#include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace std::chrono; struct BufferTestResult{ size_t bufferSize; double duration; }; struct testResults{ string filename; vector results; }; testResults testBufferSize(const string &inputPath, const string &outputPath, size_t bufferSize){ int iterations = 30; vector results; vector buffer(bufferSize); for (int i = 0; i < iterations; i++) { BufferTestResult result; result.bufferSize = bufferSize; ifstream inputFile(inputPath, ios::binary); ofstream outputFile(outputPath, ios::binary); auto start = high_resolution_clock::now(); while (inputFile.read(buffer.data(), bufferSize)) outputFile.write(buffer.data(), inputFile.gcount()); auto stop = high_resolution_clock::now(); auto duration = duration_cast(stop - start); result.duration = duration.count()/1000000.0; results.push_back(result); buffer.clear(); inputFile.close(); outputFile.close(); } testResults testResults; testResults.filename = inputPath; testResults.results = results; return testResults; } void createFile(const string &filename, size_t fileSize){ ofstream out_test(filename); minstd_rand rand_generator; random_device rand_device; rand_generator.seed(rand_device()); uniform_int_distribution distribution(0, 25); out_test.clear(); for(int i = 0; i < fileSize; i++){ char c = distribution(rand_generator) + 65; out_test << c; } out_test.close(); } int main(){ testResults results; double minTimeTaken[3] = {0,0,0}; uint64_t blockSize[3] = {0,0,0}; uint64_t testBlockSize = 0; int fileSize = 0; char filename[32]; char filename_copy[32]; map ratio_weight; map Buffer_weight; for(int j = 1; j <= 4096 ; j *= 2){ fileSize = j * 65536; minTimeTaken[0] = 0; minTimeTaken[1] = 0; minTimeTaken[2] = 0; blockSize[0] = 0; blockSize[1] = 0; blockSize[2] = 0; //Creates a file with j * 64k characters snprintf(filename, 32, "test_%dk.txt", fileSize /1024); //Creates string for copy file snprintf(filename_copy, 32, "test_%dk_copy.txt", fileSize/1024); createFile(filename, fileSize); for(int i = 1; i <= 1024; i *= 2){ testBlockSize = i * 1024; results = testBufferSize(filename, filename_copy, testBlockSize); double averageTimeTaken = 0; for(auto result : results.results){ averageTimeTaken += result.duration; } averageTimeTaken /= results.results.size(); if(averageTimeTaken < minTimeTaken[0] || minTimeTaken[0] == 0){ minTimeTaken[0] = averageTimeTaken; blockSize[0] = testBlockSize; }else if(averageTimeTaken < minTimeTaken[1] || minTimeTaken[1] == 0){ minTimeTaken[1] = averageTimeTaken; blockSize[1] = testBlockSize; }else if(averageTimeTaken < minTimeTaken[2] || minTimeTaken[2] == 0){ minTimeTaken[2] = averageTimeTaken; blockSize[2] = testBlockSize; } //cout<< "Buffer Size: " << testBlockSize << " bytes, Time taken: " << timeTaken << " microseconds" << endl; } cout << filename << endl << blockSize[0] / 1024 << "k => " << minTimeTaken[0] << " ms" << endl << blockSize[1] / 1024 << "k => " << minTimeTaken[1] << " ms" << endl << blockSize[2] / 1024 << "k => " << minTimeTaken[2] << " ms" << endl << endl; double ratios[3] = {(double)fileSize / blockSize[0], (double)fileSize / blockSize[1], (double)fileSize / blockSize[2]}; cout << "Size to best block ratio: " << endl << ratios[0] << endl << ratios[1] << endl << ratios[2] << endl << endl; int intratios[3] = {0,0,0}; intratios[0] = floor(ratios[0] * 10000); intratios[1] = floor(ratios[1] * 10000); intratios[2] = floor(ratios[2] * 10000); if(ratio_weight.find(intratios[0]) == ratio_weight.end()) ratio_weight[intratios[0]] = 6; else ratio_weight[intratios[0]] += 6; if(ratio_weight.find(intratios[1]) == ratio_weight.end()) ratio_weight[intratios[1]] = 4; else ratio_weight[intratios[1]] += 4; if(ratio_weight.find(intratios[2]) == ratio_weight.end()) ratio_weight[intratios[2]] = 3; else ratio_weight[intratios[2]] += 3; if(Buffer_weight.find(blockSize[0]) == Buffer_weight.end()) Buffer_weight[blockSize[0]] = 6; else Buffer_weight[blockSize[0]] += 6; if(Buffer_weight.find(blockSize[1]) == Buffer_weight.end()) Buffer_weight[blockSize[1]] = 4; else Buffer_weight[blockSize[1]] += 4; if(Buffer_weight.find(blockSize[2]) == Buffer_weight.end()) Buffer_weight[blockSize[2]] = 3; else Buffer_weight[blockSize[2]] += 3; } std::ofstream out("ratio_results.txt"); out << "ratio, weight" << endl; for(auto const &pair : ratio_weight){ out << pair.first << ", " << pair.second << endl; } out.close(); out.open("buffer_results.txt"); out << "buffer, weight" << endl; for(auto const &pair : Buffer_weight){ out << pair.first << ", " << pair.second << endl; } out.close(); return 0; }