Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么C++;?_C++_Multidimensional Array_Matrix - Fatal编程技术网

C++ 为什么C++;?

C++ 为什么C++;?,c++,multidimensional-array,matrix,C++,Multidimensional Array,Matrix,这可能是一个重复的问题。所以,如果你愿意,请随时标记下来。 在C++中,我了解到数组维度是连续存储在内存中的,所以我做了一个小实验,将自然数分配给大小为1600万×x1和1x1600亿的矩阵(请根据代码将代码< MasSosie>代码>更改为较小的值,这取决于内存)。下面的代码将1到160000000之间的自然数分配给矩阵a(其尺寸为1x16000000),并计算所有元素的立方体总和。相反的情况是,我通过将xdim更改为matize并将ydim更改为1来反转矩阵的维度,然后重新编译代码并再次运行

这可能是一个重复的问题。所以,如果你愿意,请随时标记下来。 在C++中,我了解到数组维度是连续存储在内存中的,所以我做了一个小实验,将自然数分配给大小为1600万×x1和1x1600亿的矩阵(请根据代码将代码< MasSosie>代码>更改为较小的值,这取决于内存)。下面的代码将1到160000000之间的自然数分配给矩阵
a
(其尺寸为1x16000000),并计算所有元素的立方体总和。相反的情况是,我通过将
xdim
更改为
matize
并将
ydim
更改为1来反转矩阵的维度,然后重新编译代码并再次运行它。矩阵是
[xdim][ydim]

#include <iostream>
#include <time.h>
using namespace std;
int main()
{
long int matsize, i, j, xdim, ydim;
long double ss;
double** a;
double time1, time2, time3;
clock_t starttime = clock();    
matsize=1600000000;
xdim=1;
ydim=matsize;   
ss=0.0;    
a= new double *[xdim];
for(i=0;i<xdim;i++)
{
    a[i]= new double[ydim];
}

time1= (double)( clock() - starttime ) / (double)CLOCKS_PER_SEC;    
cout << "allocated. time taken for allocation was " << time1 <<" seconds. computation started" << endl;    
for(i=0;i<xdim;i++)
{
    for(j=0;j<ydim;j++)
    {
        a[i][j]=(i+1)*(j+1);
        ss=ss+a[i][j]*a[i][j]*a[i][j];
    }
}
cout << "last number is " << a[xdim-1][ydim-1] << " . sum is " << ss << endl;
time2= ((double)( clock() - starttime ) / (double)CLOCKS_PER_SEC) - time1;
cout << "computation done. time taken for computation was " << time2 << " seconds" << endl;    
for(i=0;i<xdim;i++)
{
    delete [] a[i];
}
delete [] a;   
time3= ((double)( clock() - starttime ) / (double)CLOCKS_PER_SEC) - time2;
cout << "deallocated. time taken for deallocation was " << time3 << " seconds" << endl;    
cout << "the total time taken is " << (double)( clock() - starttime ) / (double)CLOCKS_PER_SEC << endl;
cout << "or " << time1+time2+time3 << " seconds" << endl; 
return 0;
}
#包括
#包括
使用名称空间std;
int main()
{
长整数矩阵,i,j,xdim,ydim;
长双ss;
双**a;
双时间1,时间2,时间3;
时钟开始时间=时钟();
matsize=160000000;
xdim=1;
ydim=matize;
ss=0.0;
a=新的双精度*[xdim];

对于(i=0;i每个单独的向量连续存储内容,包括指向向量的指针向量,但是您对new的连续调用的地址不连续,向量内部创建缓冲区的调用也不连续。因此,如果您有指向微小向量的指针向量,那么您的内存实际上是不连续的如果你有一个单一的元素向量到一个巨大的向量,那么内存是连续的,缓存将很好地工作

视觉上,快速/连续布局为:

*a--[0]
.    |
.   [0][1][2][3][4][5][...]
你的慢选择是:

.        [0]     [0]
.         \       /
*a--[0][1][2][3][4][5][...]
.    |   \    |     \
.   [0]   \[0][0]   [0]
可以在堆栈上创建多维数组,例如

int x[10][20];
在这种情况下,内存将是连续的,x[0]、x[1]等中的每个内存都是连续的(因此x[0][0]在x[0][1]之前,而不是紧靠x[1][0]之前)


为了在堆上有效地拥有一个连续的多维数组,您应该使用预期维度的乘积新建一个向量,然后编写一个包装类,方便地将维度相乘以查找特定元素。

由于数据缓存的原因,计算时间是不同的。了解CPU会加载数据当您读取内存中的某个位置时,它会预测下一次读取的位置将仅比您刚才读取的地址前几个字节

当数组被分配为
[1][N]
,元素确实是连续存储的,因此CPU的预测几乎一直都是真实的。您需要的数据几乎总是可以从CPU的缓存中获得,这比主存快几倍。CPU在执行计算时继续向前加载刚读取的位置,因此加载新的数据ata和数字相加并行进行

当您切换维度时,您添加的数字不再位于连续位置。这是因为对
new
的连续调用不会在连续内存区域中分配数据:内存管理库为“簿记”添加几个字节它总是分配一些最小大小的内存块,通常大于
double
。当您请求一个小于最小值的内存块时,分配的区域会被填充。因此,在最佳情况下,
double
可能会相隔20个字节*-足以使从相邻内存位置提前读取的影响。这就是为什么CPU在从不同位置加载数据时被迫等待的原因。这会使计算速度减慢几倍。

*在最坏的情况下,根据运行代码之前执行的分配和取消分配,值可能会被放置任意远。

谢谢。因此,从技术上讲,尽管我在处理2D数组,但如果我将所有内容连续存储在一维数组中,计算速度会更快?@guddu:是的,如果使用向量,则会加快计算速度如果有大量的数据和使用堆栈内存是一个问题,我想做的是。我认为我已经看到了30/40个线类来包装一个向量,同时允许一个方便的符号,比如<代码>向量(x,y)< /> >(做什么<代码> vector [x,y] < /c>理想地做,但是不能在C++中给出,y评估和丢弃x,然后评估和使用y)在一些类似问题的stackoverflow答案中,如果您不喜欢编写这样的包装,可能值得搜索一下。明白了。谢谢:)这将有助于LOTA对该方法进行轻微改进,对于许多操作来说,将第一维度四舍五入为2倍或4个浮点的倍数是值得的,因为这允许SSE操作用于矩阵乘法等。谢谢@Raymond,我应该仔细查看:(“你的双字节可能会相隔20个字节”-这忽略了许多问题,包括碎片。如果以前有很多类似大小的分配,其中随机的一小部分已经被释放,你很可能会填补释放的“漏洞”"跨原始内存区域,并且不一定按照与您以后请求的顺序相关的顺序。此外,即使双工是连续分配的,也会有另一层间接性,在对每一个都使用不同的指针时。@TonyD当然,我说的是最佳情况下的场景,当时什么都没有分配/dea在运行实验之前分配。