Remember just learning C + + that would have bothered me, and then slowly formed the habit of using a one-dimensional array at any time, then learned that in a one-dimensional array of first-column element address to make two-dimensional call method. Can never think of this problem, recently wrote a bit of code test, although still some unknown, but the results are very interesting.
In order to avoid compiler optimizations, the use of write operations, int, the test is divided into different sizes of space, the same size and space of different rows and columns. Records line-by-row writes, write-by-column, write-by-interval, space requests, and time to release.
Test code
Application and release of one-dimensional arrays
1 // Create 2 int New int [N_row * N_col]; 3 4 // Free 5 Delete [] m;
Application and release of two-dimensional arrays
1 //Create2 int**m =New int*[N_row];3 for(inti =0; i < N_row; ++i)4M[i] =New int[N_col];5 6 // Free7 for(inti =0; i < N_row; ++i)8 Delete [] m[i];9delete [] m;
Line-wise Write
1 for(inti =0; i < N_row; ++i)2 {3 for(intj =0; J < N_col; ++j)4 {5Matrix[i * N_col + j] =answer;6 //Matrix[i][j] = answer;7 } 8}
Column-wise Write
1 for(intj =0; J < N_col; ++j)2 {3 for(inti =0; i < N_row; ++i)4 {5Matrix[i * N_col + j] =answer;6 //Matrix[i][j] = answer;7 } 8}
Write by interval
1 for(inti =0; i < N_row; ++i)2 {3 for(intj =0; J < N_col; ++j)4 {5 introw = i *7%N_row;6 intCol = J * One%N_col;7Matrix[i * N_col + j] =answer;8 //Matrix[i][j] = answer;9 }Ten}
It's not quite certain that the test is reasonable, but it's mostly about what I'm trying to measure. It is important to note that line-by-row writing is for simplicity I'm writing a variable called answer, but the situation should be more generalized, otherwise it might be quicker to use memset or Std::fill? Write-by-column code example of a typical reverse code for undergraduate course level, here is just for testing.
The main differences from the point of view of compilation are in the following two sentences:
1 matrix[i * n_col + j] = answer; 2 matrix[i][j] = answer;
Take a look at the corresponding assembly code:
1 ; Matrix[i * n_col + j] = answer;2 movedx, DWORD PTR _I$3[EBP]3 Imuledx, DWORD PTR _N_COL$[EBP]4 Addedx, DWORD PTR _J$2[EBP]5 moveax, DWORD PTR _MATRIX$[EBP]6 movecx, DWORD PTR _ANSWER$[EBP]7 movDWORD PTR [eax+edx*4], ECX
1 ; Matrix[i][j] = answer;2 movecx, DWORD PTR _I$4[EBP]3 movedx, DWORD PTR _MATRIX$[EBP]4 movEAX, DWORD PTR [edx+ecx*4]5 movecx, DWORD PTR _J$3[EBP]6 movedx, DWORD PTR _ANSWER$[EBP]7 movDWORD PTR [eax+ecx*4], edx
Are 6 instructions, the system is not good, so I can not see which is faster. This is the Visual Studio compiled, because I am not familiar with GCC, do not know how to generate such an intuitive assembly and C + + correspondence, the efficiency of Linux is still higher than windows, but in order to unify, after the test is based on Windows. Of course, there is no optimization of the compilation, if the Optimization (VS/O2), assembly instructions are probably also 4, 5, because the structure of the/O2 optimized assembly code is not very intuitive, here is not affixed. (On the other hand, because my compilation level is weak, I don't see anything)
In addition to directly using a and two-dimensional arrays, you can also do a two-dimensional array of one-dimensional arrays, the method is a one-dimensional array of all corresponding to the first column of the element's address as an array of pointers, which is essentially a one-dimensional array, but implemented a formal two-dimensional array call, this method space application code is as follows
1 // 2 int **m = new int *[n_row]; 3 int *block = new int [N_row * N_col]; 4 int i = 0 ; i < N_row; ++5 m[i] = &block[i * N_col]; 6 return m;
The code that is freed is the same as a two-dimensional array.
The advantage of simulating two-dimensional invocation with one-dimensional array is that the continuity of the memory space is ensured, and the code of the two-dimensional invocation is maintained easily. However, it is important to note that the two-dimensional index, the assembly code and the two-dimensional array is the same.
Test results
Execute the above code, and under different rows and columns, the loop executes the average and the result is as follows:
application and release of memory :
Row-wise Access
Column-wise Access
Access by interval
Analysis
Memory Continuity : a one-dimensional array clearly has better continuity than a two-dimensional array, and I forget where I used to see it. The character drawing of an image illustrates the difference between a one-dimensional array and a two-dimensional array, presumably the following:
One-dimensional arrays:
┌--┬--┬--┬--┬-| | | | | ... └--┴--┴--┴--┴-
Two-dimensional arrays:
┌--┬--┬--┬--┬-| | | | | ... └--┴--┴--┴--┴-| | | | | V | |┌--┬--┬--┬- | | | | | | | V |┌--┬--┬--┬--┬-| | | | | | |.. |└--┴--┴--┴--┴- v┌--┬--┬--┬--┬--┬-| | | | | | ... └--┴--┴--┴--┴--┴-
Cache Hit Ratio : The Cache is SRAM, memory is DRAM, the efficiency is much worse, so if you can increase the hit rate in the cache, the efficiency can be improved a lot. In fact, this is related to the previous one, obviously the continuous memory hit rate will be high, but if the application of memory space is very large that the specific problem to be analyzed.
instruction Execution Speed : Because of the early system did not learn, so I do not know how much impact, and now the computer is multi-core, as do not engage in more accounting method of the people, do not understand how much impact.
The control results can be seen basically the efficiency of a one-dimensional array of two-dimensional arrays, especially memory applications and small memory accesses, overall efficiency on one-dimensional arrays > one-dimensional arrays of two-dimensional reference > two-dimensional arrays. But there are also interesting findings: 1. When the memory space is small, one-dimensional array is more efficient than the two-dimensional array, while the large memory becomes slower. 2) per-column access basically conforms to expectations, one-dimensional array and one-dimensional array two-dimensional index efficiency close, two-dimensional index efficiency is slightly lower, but are better than the two-dimensional array. 3) when accessed at intervals, one-dimensional arrays are significantly faster than row-by-line access, and do not understand why, if my computer is multi-core impact? Or does the O2 compilation of VS work?
Pure egg ache test, also is quite not rigorous, hoped has the system knowledge more rich danale pointing twos.
[C + +] Two-dimensional arrays or one-dimensional arrays?