├── README.md ├── lab1 ├── insDependDist.cpp └── 体系结构实验一报告.pdf ├── lab2 ├── brchPredict.cpp └── 体系结构实验二.pdf ├── lab3 ├── cacheModel.cpp ├── test.sh └── 体系结构实验三报告.pdf └── lab4 └── lab4_student ├── cache_test.cpp ├── matrix_mul.cpp ├── src ├── cache_test.cpp ├── cache_test.exe ├── matrix_mul.cpp └── matrix_mul.exe └── 实验报告4.pdf /README.md: -------------------------------------------------------------------------------- 1 | # 哈尔滨工业大学(深圳)2021年计算机系体结构实验 2 | 3 | 今年实验可以选择自选实验与基础实验,两者取其一,本仓库收录基础实验内容。 4 | 5 | 基础实验基本上是在Linux虚拟机上完成软件层面的模拟,总体难度不大,除了最后一个实验需要与CPU斗智斗勇。 6 | -------------------------------------------------------------------------------- /lab1/insDependDist.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2002-2020 Intel Corporation. 3 | * 4 | * This software is provided to you as Sample Source Code as defined in the accompanying 5 | * End User License Agreement for the Intel(R) Software Development Products ("Agreement") 6 | * section 1.L. 7 | * 8 | * This software and the related documents are provided as is, with no express or implied 9 | * warranties, other than those that are expressly stated in the License. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include "pin.H" 16 | using std::cerr; 17 | using std::ofstream; 18 | using std::ios; 19 | using std::string; 20 | using std::endl; 21 | using std::vector; 22 | 23 | ofstream OutFile; 24 | 25 | // Convenience data structure 26 | typedef uint32_t reg_t; 27 | struct Registers 28 | { 29 | vector read; 30 | vector write; 31 | }; 32 | 33 | // Global variables 34 | // The array storing the distance frequency between two dependant instructions 35 | UINT64 *insDependDistance; 36 | INT32 maxSize; 37 | INT32 insPointer = 0; 38 | INT32 lastInsPointer[1024] = { 0 }; 39 | 40 | // This function is called before every instruction is executed. 41 | // You have to edit this function to determine the dependency distance 42 | // and populate the insDependDistance data structure. 43 | VOID updateInsDependDistance(VOID *v) 44 | { 45 | // Update the instruction pointer 46 | ++insPointer; 47 | 48 | // regs contains the registers read and written by this instruction. 49 | // regs->read contains the registers read. 50 | // regs->write contains the registers written. 51 | Registers *regs = (Registers*)v; 52 | 53 | /* TODO: 54 | 本函数需完成以下2个任务: 55 | A. 遍历regs->read向量, 利用lastInsPointer数组计算当前指令的被读寄存器的依赖距离, 56 | 即对任意的r属于regs->read, 其依赖距离 = 当前PC值 - lastInsPointer[r]. 57 | B. 遍历regs->write向量, 利用lastInsPointer数组记录当前指令的被写寄存器所对应的PC值, 58 | 即对任意的r属于regs->write, 将当前PC值赋值给lastInsPointer[r]. 59 | 思考: A和B哪个应该先执行? 请通过举例来说明理由. 60 | */ 61 | // 是否需要把下面两个调换? 62 | // Update the lastInstructionCount for the written registers 63 | // for (vector::iterator it = regs->write.begin(); it != regs->write.end(); it++) 64 | // lastInsPointer[*it] = insPointer; // TODO 65 | 66 | for (vector::iterator it = regs->read.begin(); it != regs->read.end(); it++) 67 | { 68 | reg_t reg = *it; 69 | 70 | if (lastInsPointer[reg] > 0) 71 | { 72 | // Compute the dependency distance 73 | INT32 distance = insPointer - lastInsPointer[reg];// TODO 74 | 75 | // Populate the insDependDistance array 76 | if (distance <= maxSize) 77 | insDependDistance[distance-1]++;// TODO 78 | } 79 | } 80 | 81 | for (vector::iterator it = regs->write.begin(); it != regs->write.end(); it++) 82 | lastInsPointer[*it] = insPointer; // TODO 83 | } 84 | 85 | // Pin calls this function every time a new instruction is encountered 86 | VOID Instruction(INS ins, VOID *v) 87 | { 88 | // regs stores the registers read, written by this instruction 89 | Registers* regs = new Registers(); 90 | 91 | // Find all the register written 92 | for (uint32_t iw = 0; iw < INS_MaxNumWRegs(ins); iw++) 93 | { 94 | // 获取当前指令中被写的寄存器(即目的寄存器) 95 | REG wr = INS_RegW(ins, iw); 96 | // 获取寄存器名 97 | wr = REG_FullRegName(wr); 98 | if (!REG_valid(wr)) 99 | continue; 100 | 101 | // 将被写寄存器保存到regs向量当中 102 | if (std::find(regs->write.begin(), regs->write.end(), wr) == regs->write.end()) 103 | regs->write.push_back(wr); 104 | } 105 | 106 | // Find all the registers read 107 | for (uint32_t ir = 0; ir < INS_MaxNumRRegs(ins); ir++) 108 | { 109 | REG rr = INS_RegR(ins, ir);/* TODO */ 110 | rr = REG_FullRegName(rr); 111 | if (!REG_valid(rr)) 112 | continue; 113 | 114 | if (std::find(regs->read.begin(), regs->read.end(), rr) == regs->read.end()) 115 | regs->read.push_back(rr); 116 | /* 117 | TODO 118 | */ 119 | } 120 | 121 | // Insert a call to the analysis function -- updateInsDependDistance -- before every instruction. 122 | // Pass the regs structure to the analysis function. 123 | INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)updateInsDependDistance, IARG_PTR, (void*)regs, IARG_END); 124 | } 125 | 126 | // This knob sets the output file name 127 | KNOB KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "insDependDist.csv", "specify the output file name"); 128 | 129 | // This knob will set the maximum distance between two dependant instructions in the program 130 | KNOB KnobMaxDistance(KNOB_MODE_WRITEONCE, "pintool", "s", "100", "specify the maximum distance between two dependant instructions in the program"); 131 | 132 | // This function is called when the application exits 133 | VOID Fini(INT32 code, VOID *v) 134 | { 135 | // Write to a file since cout and cerr maybe closed by the application 136 | OutFile.setf(ios::showbase); 137 | for (INT32 i = 0; i < maxSize; i++) 138 | OutFile << insDependDistance[i] << ","; 139 | OutFile.close(); 140 | } 141 | 142 | /* ===================================================================== */ 143 | /* Print Help Message */ 144 | /* ===================================================================== */ 145 | 146 | INT32 Usage() 147 | { 148 | cerr << "This tool counts the number of dynamic instructions executed" << endl; 149 | cerr << endl << KNOB_BASE::StringKnobSummary() << endl; 150 | return -1; 151 | } 152 | 153 | /* ===================================================================== */ 154 | /* Main */ 155 | /* ===================================================================== */ 156 | /* argc, argv are the entire command line: pin -t -- ... */ 157 | /* ===================================================================== */ 158 | 159 | int main(int argc, char * argv[]) 160 | { 161 | // Initialize pin 162 | if (PIN_Init(argc, argv)) return Usage(); 163 | 164 | OutFile.open(KnobOutputFile.Value().c_str()); 165 | maxSize = atoi(KnobMaxDistance.Value().c_str()); 166 | 167 | // Initializing depdendancy Distance 168 | insDependDistance = new UINT64[maxSize]; 169 | memset((void*)insDependDistance, 0, sizeof(UINT64) * maxSize); 170 | 171 | // Register Instruction to be called to instrument instructions 172 | INS_AddInstrumentFunction(Instruction, 0); 173 | 174 | // Register Fini to be called when the application exits 175 | PIN_AddFiniFunction(Fini, 0); 176 | 177 | // Start the program, never returns 178 | PIN_StartProgram(); 179 | 180 | return 0; 181 | } 182 | 183 | -------------------------------------------------------------------------------- /lab1/体系结构实验一报告.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yikai-coder/HITSZ-CAL-2021/3b2ce9f28e7dc73e11352c6ff86f53096173f850/lab1/体系结构实验一报告.pdf -------------------------------------------------------------------------------- /lab2/brchPredict.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yikai-coder/HITSZ-CAL-2021/3b2ce9f28e7dc73e11352c6ff86f53096173f850/lab2/brchPredict.cpp -------------------------------------------------------------------------------- /lab2/体系结构实验二.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yikai-coder/HITSZ-CAL-2021/3b2ce9f28e7dc73e11352c6ff86f53096173f850/lab2/体系结构实验二.pdf -------------------------------------------------------------------------------- /lab3/cacheModel.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yikai-coder/HITSZ-CAL-2021/3b2ce9f28e7dc73e11352c6ff86f53096173f850/lab3/cacheModel.cpp -------------------------------------------------------------------------------- /lab3/test.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | test_program=(gcc astar zeusmp tonto) 3 | pin_program=cacheModel.so 4 | output_program=result_cmp_2.txt 5 | make 6 | # ../pin -t obj-intel64/cacheModel.so -- runspec --size=test --noreportable gcc 7 | # ../pin -t obj-intel64/cacheModel.so -- runspec --size=test --noreportable astar 8 | # ../pin -t obj-intel64/cacheModel.so -- runspec --size=test --noreportable zeusmp 9 | # ../pin -t obj-intel64/cacheModel.so -- runspec --size=test --noreportable tonto 10 | for program in ${test_program[*]}: 11 | do 12 | echo ${program}: | tee -a ${output_program} 13 | ../pin -t obj-intel64/${pin_program} -- runspec --size=test --noreportable --nobuild --iteration=1 ${program} | tee -a ${output_program} 14 | done -------------------------------------------------------------------------------- /lab3/体系结构实验三报告.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yikai-coder/HITSZ-CAL-2021/3b2ce9f28e7dc73e11352c6ff86f53096173f850/lab3/体系结构实验三报告.pdf -------------------------------------------------------------------------------- /lab4/lab4_student/cache_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | #define ARRAY_SIZE (1 << 28) // test array size is 2^28 8 | typedef unsigned char BYTE; // define BYTE as one-byte type 9 | #define SIZE_TEST_TIMES 123456789 10 | #define WAY_TEST_TIMES 99999 11 | 12 | BYTE array[ARRAY_SIZE]; // test array 13 | int L1_cache_size = 1 << 15; 14 | int L2_cache_size = 1 << 18; 15 | int L1_cache_block = 64; 16 | int L2_cache_block = 64; 17 | int L1_way_count = 8; 18 | int L2_way_count = 4; 19 | int write_policy = 0; // 0 for write back ; 1 for write through 20 | 21 | // have an access to arrays with L2 Data Cache'size to clear the L1 cache 22 | void Clear_L1_Cache() 23 | { 24 | memset(array, 0, L2_cache_size); 25 | } 26 | 27 | // have an access to arrays with ARRAY_SIZE to clear the L2 cache 28 | void Clear_L2_Cache() 29 | { 30 | memset(&array[L2_cache_size + 1], 0, ARRAY_SIZE - L2_cache_size); 31 | } 32 | 33 | int Test_Cache_Size(int index, int *avg_time) 34 | { 35 | int size; 36 | int data_size; 37 | char data; 38 | clock_t begin, end; 39 | size = index; 40 | for (int i = 0; i < 5; i++) 41 | { 42 | data_size = (1 << (size + 10)); 43 | Clear_L1_Cache(); 44 | Clear_L2_Cache(); 45 | begin = clock(); 46 | for (int j = 0; j < SIZE_TEST_TIMES; ++j) 47 | { 48 | data += array[(rand() * rand()) % data_size]; 49 | } 50 | end = clock(); 51 | avg_time[i] = end - begin; 52 | size++; 53 | } 54 | 55 | int temp, process_time; 56 | size = index; 57 | int cache_size_result = (1 << size); 58 | process_time = avg_time[1] - avg_time[0]; 59 | for (int i = 0; i < 5; i++) 60 | { 61 | cout << "Test_Array_Size = " << (1 << size) << "KB, "; 62 | cout << "Average access time = " << avg_time[i] << "ms" << endl; 63 | if (i < 4) 64 | { 65 | temp = avg_time[i + 1] - avg_time[i]; 66 | if (temp > process_time) 67 | { 68 | cache_size_result = (1 << size); 69 | process_time = temp; 70 | } 71 | } 72 | size++; 73 | } 74 | return cache_size_result; 75 | } 76 | 77 | int Test_Cache_Block(int index, int *avg_time) 78 | { 79 | 80 | int size; 81 | int data_size; 82 | char data; 83 | clock_t begin, end; 84 | unsigned int temp; 85 | temp = index; 86 | for (int i = 0; i < 8; ++i) 87 | { 88 | begin = clock(); 89 | for (int j = 0; j < temp; ++j) 90 | { 91 | for (int k = 0; k < ARRAY_SIZE; k += temp) 92 | { 93 | data += array[k]; 94 | } 95 | } 96 | end = clock(); 97 | avg_time[i] = end - begin; 98 | temp = temp << 1; 99 | } 100 | 101 | temp = index; 102 | int process_time = avg_time[1] - avg_time[0], temp_time; 103 | int cache_block_result; 104 | for (int i = 0; i < 8; ++i) 105 | { 106 | cout << "Block_Size = " << temp << " B, "; 107 | cout << "Average access time = " << avg_time[i] << "ms " << endl; 108 | if (i < 7) 109 | { 110 | temp_time = avg_time[i + 1] - avg_time[i]; 111 | if (temp_time > process_time) 112 | { 113 | cache_block_result = (1 << size); 114 | process_time = temp_time; 115 | } 116 | } 117 | size++; 118 | temp = temp << 1; 119 | } 120 | return cache_block_result; 121 | } 122 | 123 | int Test_Cache_Way_Count(int array_size, int index, int *avg_time) 124 | { 125 | int temp; 126 | int array_jump; 127 | char data; 128 | clock_t begin, end, temp_time; 129 | int process_time, way_count_result; 130 | temp = index; 131 | for (int i = 0; i < 5; ++i) 132 | { 133 | array_jump = array_size / temp; 134 | begin = clock(); 135 | for (int j = 0; j < WAY_TEST_TIMES; ++j) 136 | { 137 | for (int k = 0; k < temp; k += 2) 138 | { 139 | memset(&array[k * array_jump], 0, array_jump); 140 | } 141 | } 142 | end = clock(); 143 | avg_time[i] = end - begin; 144 | temp = temp << 1; 145 | } 146 | 147 | temp = index; 148 | process_time = avg_time[1] - avg_time[0]; 149 | way_count_result = temp / 2; 150 | for (int i = 0; i < 5; ++i) 151 | { 152 | cout << "Way_Count = " << temp / 2 << ", "; 153 | cout << "Average access time = " << avg_time[i] << "ms " << endl; 154 | if (i < 4) 155 | { 156 | temp_time = avg_time[i + 1] - avg_time[i]; 157 | if (temp_time > process_time) 158 | { 159 | way_count_result = temp / 2; 160 | process_time = temp_time; 161 | } 162 | } 163 | temp = temp << 1; 164 | } 165 | return way_count_result; 166 | } 167 | 168 | int L1_DCache_Size() 169 | { 170 | cout << "*****************************************************" << endl; 171 | cout << "L1_Data_Cache_Test" << endl; 172 | int avg_time[5]; 173 | int index = 3; 174 | int result; 175 | result = Test_Cache_Size(index, avg_time); 176 | cout << "L1_Data_Cache_Size is " << result << "KB" << endl; 177 | cout << "*****************************************************" << endl; 178 | return result << 10; 179 | } 180 | 181 | int L2_Cache_Size() 182 | { 183 | cout << "*****************************************************" << endl; 184 | cout << "L2_Data_Cache_Test" << endl; 185 | int avg_time[5]; 186 | int index = 6; 187 | int result; 188 | result = Test_Cache_Size(index, avg_time); 189 | cout << "L2_Cache_Size is " << result << "KB" << endl; 190 | cout << "*****************************************************" << endl; 191 | return result << 10; 192 | } 193 | 194 | int L1_DCache_Block() 195 | { 196 | cout << "*****************************************************" << endl; 197 | cout << "L1_DCache_Block_Test" << endl; 198 | int index = 1; 199 | int avg_time[8]; 200 | int result; 201 | result = Test_Cache_Block(index, avg_time); 202 | cout << "L1_Data_Block_Size is " << result << "B" << endl; 203 | cout << "*****************************************************" << endl; 204 | return result; 205 | } 206 | 207 | int L2_Cache_Block() 208 | { 209 | cout << "*****************************************************" << endl; 210 | cout << "L2_Cache_Block_Test" << endl; 211 | int index = 1; 212 | int avg_time[8]; 213 | int result; 214 | result = Test_Cache_Block(index, avg_time); 215 | cout << "L2_Block_Size is " << result << "B" << endl; 216 | cout << "*****************************************************" << endl; 217 | return result; 218 | } 219 | 220 | int L1_DCache_Way_Count() 221 | { 222 | cout << "*****************************************************" << endl; 223 | cout << "L1_DCache_Way_Count" << endl; 224 | int array_size = L1_cache_size << 1; 225 | int index = 2; 226 | int avg_time[5]; 227 | int result; 228 | result = Test_Cache_Way_Count(array_size, index, avg_time); 229 | cout << "L1_DCache_Way_Count is " << result << endl; 230 | cout << "*****************************************************" << endl; 231 | } 232 | 233 | int L2_Cache_Way_Count() 234 | { 235 | cout << "*****************************************************" << endl; 236 | cout << "L2_Cache_Way_Count" << endl; 237 | int array_size = L2_cache_size << 1; 238 | int index = 2; 239 | int avg_time[5]; 240 | int result; 241 | result = Test_Cache_Way_Count(array_size, index, avg_time); 242 | cout << "L2_Way_Count is " << result << endl; 243 | cout << "*****************************************************" << endl; 244 | } 245 | 246 | int main() 247 | { 248 | SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); 249 | SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); 250 | // L1_cache_size = L1_DCache_Size(); 251 | // L2_cache_size = L2_Cache_Size(); 252 | // L1_cache_block = L1_DCache_Block(); 253 | // L2_cache_block = L2_Cache_Block(); 254 | L1_way_count = L1_DCache_Way_Count(); 255 | L2_way_count = L2_Cache_Way_Count(); 256 | system("pause"); 257 | return 0; 258 | } 259 | -------------------------------------------------------------------------------- /lab4/lab4_student/matrix_mul.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main() 9 | { 10 | clock_t start, finish; 11 | clock_t start1, finish1; 12 | 13 | int i,j,k; 14 | //initial two 1000*1000 matrix 15 | int (*a)[1000],(*b)[1000]; 16 | a = new int[1000][1000]; 17 | b = new int[1000][1000]; 18 | 19 | 20 | for(i = 0; i < 1000; i++) 21 | { 22 | for(j = 0; j < 1000; j++) 23 | { 24 | a[i][j] = i % (j+1); 25 | b[i][j] = i / (j+1); 26 | } 27 | } 28 | //store A*B result 29 | int (*c)[1000],(*d)[1000]; 30 | c = new int[1000][1000]; 31 | d = new int[1000][1000]; 32 | 33 | //initial 0 34 | memset(c,0, 1000*1000*sizeof(int)); 35 | memset(d,0, 1000*1000*sizeof(int)); 36 | 37 | start = clock(); 38 | for(i = 0; i < 1000; i++) 39 | { 40 | for(j = 0; j < 1000; j++) 41 | { 42 | for (k = 0; k < 1000; k++) 43 | { 44 | c[i][j] += a[i][k] * b[k][j]; 45 | } 46 | 47 | } 48 | } 49 | finish = clock(); 50 | 51 | start1 = clock(); 52 | 53 | //====================================================== 54 | //add your own code 55 | //====================================================== 56 | // Plan A 57 | for(i = 0; i < 1000; i++) 58 | { 59 | for(j = 0; j < 1000; j++) 60 | { 61 | for (k = 0; k < 1000; k++) 62 | { 63 | d[i][k] += a[i][j] * b[j][k]; 64 | } 65 | 66 | } 67 | } 68 | // Plan B 69 | // int (*bT)[1000] = new int[1000][1000]; 70 | // memset(bT, 0, 1000*1000*sizeof(int)); 71 | // for (i = 0; i < 1000; i ++) { 72 | // for (j = 0; j < 1000; j ++) { 73 | // bT[j][i] = b[i][j]; 74 | // } 75 | // } 76 | // for(i = 0; i < 1000; i++) 77 | // { 78 | // for(j = 0; j < 1000; j++) 79 | // { 80 | // for (k = 0; k < 1000; k++) 81 | // { 82 | // d[i][j] += a[i][k] * bT[j][k]; 83 | // } 84 | 85 | // } 86 | // } 87 | 88 | 89 | 90 | 91 | 92 | 93 | finish1 = clock(); 94 | 95 | 96 | //compare the results 97 | for(i = 0; i < 1000; i++) 98 | { 99 | for(j = 0; j < 1000; j++) 100 | { 101 | if (c[i][j] != d[i][j]) 102 | { 103 | cout<<"you have got an error in algorithm modification!"< 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | #define ARRAY_SIZE (1 << 28) // test array size is 2^28 11 | typedef unsigned char BYTE; // define BYTE as one-byte type 12 | typedef chrono::duration milliseconds; // 毫秒 13 | 14 | 15 | BYTE array[ARRAY_SIZE]; // test array 16 | int L1_cache_size = 1 << 15; 17 | int L2_cache_size = 1 << 18; 18 | int L1_cache_block = 64; 19 | int L2_cache_block = 64; 20 | int L1_way_count = 8; 21 | int L2_way_count = 4; 22 | int write_policy = 0; // 0 for write back ; 1 for write through 23 | 24 | int test_times = 11451419 * 10; 25 | 26 | 27 | // have an access to arrays with L2 Data Cache'size to clear the L1 cache 28 | void Clear_L1_Cache() { 29 | memset(array, 0, L2_cache_size); 30 | } 31 | 32 | // have an access to arrays with ARRAY_SIZE to clear the L2 cache 33 | void Clear_L2_Cache() { 34 | memset(&array[L2_cache_size + 1], 0, ARRAY_SIZE - L2_cache_size); 35 | } 36 | 37 | // int test 38 | void random_array() 39 | { 40 | srand(time(NULL)); 41 | for(int i = 0; i < ARRAY_SIZE; i++) 42 | array[i] = rand(); 43 | } 44 | 45 | int L1_DCache_Size() { 46 | cout << "L1_Data_Cache_Test" << endl; 47 | //add your own code 48 | Clear_L1_Cache(); 49 | Clear_L2_Cache(); 50 | 51 | srand(time(NULL)); 52 | int tmp = 0; 53 | // 随机数生成 54 | // std::random_device rd; //Will be used to obtain a seed for the random number engine 55 | // std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd() 56 | for(int gap = L1_cache_size>>3; gap<=(L1_cache_size<<1); gap=gap<<1) 57 | { 58 | cout<<"Test array size "<(t2 - t1); 67 | double dt = time_span.count(); 68 | // double elapsed_time = (double)(end-start)/CLOCKS_PER_SEC * 1000; 69 | cout<<"Average access time: "<
(t2 - t1); 89 | // double dt = time_span.count(); 90 | // cout<<"Test L1 cache "<
>5; test_size(t2 - t1); 107 | // double dt = time_span.count(); 108 | // cout<<"Test size "<>5; gap<=(L2_cache_size<<1); gap=gap<<1) 128 | // { 129 | // cout<<"Test array size "< distrib(0, gap-1); 133 | // // 生成随机访问序列 134 | // vector access_array; 135 | // for(int i = 0; i < test_times; i++) 136 | // { 137 | // access_array.push_back(distrib(gen)); 138 | // } 139 | // // clock_t start = clock(); 140 | // chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now(); 141 | // for(int i = 0; i < test_times; i++) 142 | // { 143 | // // int idx = (rand() % (ARRAY_SIZE/gap)) * gap + rand(); 144 | // // long idx = (rand() % gap + rand() % * gap) % ARRAY_SIZE; 145 | // // cout< time_span = chrono::duration_cast>(t2 - t1); 151 | // milliseconds time_span = chrono::duration_cast(t2 - t1); 152 | // double dt = time_span.count(); 153 | // // double elapsed_time = (double)(end-start)/CLOCKS_PER_SEC * 1000; 154 | // cout<<"Average access time: "<
>5; test_size(t2 - t1); 174 | // double dt = time_span.count(); 175 | // cout<<"Test size "<>3; gap<=(L2_cache_size<<1); gap=gap<<1) 190 | { 191 | cout<<"Test array size "<(t2 - t1); 200 | double dt = time_span.count(); 201 | // double elapsed_time = (double)(end-start)/CLOCKS_PER_SEC * 1000; 202 | cout<<"Average access time: "<
(t2 - t1); 227 | double dt = time_span.count(); 228 | cout<<"Gap = "<(t2 - t1); 250 | double dt = time_span.count(); 251 | cout<<"Gap = "<(t2 - t1); 272 | double dt = time_span.count(); 273 | cout<<"way = "<(t2 - t1); 294 | double dt = time_span.count(); 295 | cout<<"way = "< 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | int main() 9 | { 10 | clock_t start, finish; 11 | clock_t start1, finish1; 12 | 13 | int i,j,k; 14 | //initial two 1000*1000 matrix 15 | int (*a)[1000],(*b)[1000]; 16 | a = new int[1000][1000]; 17 | b = new int[1000][1000]; 18 | 19 | 20 | for(i = 0; i < 1000; i++) 21 | { 22 | for(j = 0; j < 1000; j++) 23 | { 24 | a[i][j] = i % (j+1); 25 | b[i][j] = i / (j+1); 26 | } 27 | } 28 | //store A*B result 29 | int (*c)[1000],(*d)[1000]; 30 | c = new int[1000][1000]; 31 | d = new int[1000][1000]; 32 | 33 | //initial 0 34 | memset(c,0, 1000*1000*sizeof(int)); 35 | memset(d,0, 1000*1000*sizeof(int)); 36 | 37 | start = clock(); 38 | for(i = 0; i < 1000; i++) 39 | { 40 | for(j = 0; j < 1000; j++) 41 | { 42 | for (k = 0; k < 1000; k++) 43 | { 44 | c[i][j] += a[i][k] * b[k][j]; 45 | } 46 | 47 | } 48 | } 49 | finish = clock(); 50 | 51 | start1 = clock(); 52 | 53 | //====================================================== 54 | //add your own code 55 | //====================================================== 56 | // Plan A 57 | for(i = 0; i < 1000; i++) 58 | { 59 | for(j = 0; j < 1000; j++) 60 | { 61 | for (k = 0; k < 1000; k++) 62 | { 63 | d[i][k] += a[i][j] * b[j][k]; 64 | } 65 | 66 | } 67 | } 68 | // Plan B 69 | // int (*bT)[1000] = new int[1000][1000]; 70 | // memset(bT, 0, 1000*1000*sizeof(int)); 71 | // for (i = 0; i < 1000; i ++) { 72 | // for (j = 0; j < 1000; j ++) { 73 | // bT[j][i] = b[i][j]; 74 | // } 75 | // } 76 | // for(i = 0; i < 1000; i++) 77 | // { 78 | // for(j = 0; j < 1000; j++) 79 | // { 80 | // for (k = 0; k < 1000; k++) 81 | // { 82 | // d[i][j] += a[i][k] * bT[j][k]; 83 | // } 84 | 85 | // } 86 | // } 87 | 88 | 89 | 90 | 91 | 92 | 93 | finish1 = clock(); 94 | 95 | 96 | //compare the results 97 | for(i = 0; i < 1000; i++) 98 | { 99 | for(j = 0; j < 1000; j++) 100 | { 101 | if (c[i][j] != d[i][j]) 102 | { 103 | cout<<"you have got an error in algorithm modification!"<