使用多维阵列优化C的性能与内存优化

使用多维阵列优化C的性能与内存优化,c,optimization,memory-management,multidimensional-array,C,Optimization,Memory Management,Multidimensional Array,我正努力在两种优化之间做出选择,以便为泊松方程建立一个数值解算器 基本上,我有一个二维数组,第一行需要n双精度,第二行需要n/2,第三行需要n/4,依此类推 现在,我的困难是决定是否使用连续的2d数组网格[m][n],对于大型n,该数组将有许多未使用的零,但可能会减少缓存未命中的机会。另一种更节省内存的方法是动态地将指针数组分配给大小不断减小的数组。这在内存存储方面效率要高得多,但它是否会潜在地影响性能 我想我并不清楚这种情况下的权衡。有人能帮忙吗 作为参考,我对每种情况下的内存需求做了一个很好

我正努力在两种优化之间做出选择,以便为泊松方程建立一个数值解算器

基本上,我有一个二维数组,第一行需要
n
双精度,第二行需要
n/2
,第三行需要
n/4
,依此类推

现在,我的困难是决定是否使用连续的2d数组
网格[m][n]
,对于大型
n
,该数组将有许多未使用的零,但可能会减少缓存未命中的机会。另一种更节省内存的方法是动态地将指针数组分配给大小不断减小的数组。这在内存存储方面效率要高得多,但它是否会潜在地影响性能

我想我并不清楚这种情况下的权衡。有人能帮忙吗

作为参考,我对每种情况下的内存需求做了一个很好的绘图:

您可以使用单个数组,自己计算偏移量

size_t get_offset(int n, int row, int column) {
    size_t offset = column;
    while (row--) {
        offset += n;
        n << 1;
    }
    return offset;
}

double * array = calloc(sizeof(double), get_offset(n, 64, 0));

您可以使用单个数组,自己计算偏移量

size_t get_offset(int n, int row, int column) {
    size_t offset = column;
    while (row--) {
        offset += n;
        n << 1;
    }
    return offset;
}

double * array = calloc(sizeof(double), get_offset(n, 64, 0));

构建一个自定义数组,该数组将遵循您设置的规则

该实现将使用一个简单的1d连续数组。您将需要一个函数,该函数将返回给定行的数组开头。大概是这样的:

int* Get( int* array , int n , int row )   //might contain logical errors
{
    int pos = 0 ;
    while( row-- )
    {
        pos += n ;
        n /= 2 ;
    }

    return array + pos ;
}
其中
n
与您描述的n相同,并且在每次迭代中向下舍入

每整行只需调用此函数一次


此函数不会花费超过O(logn)的时间,但如果需要,可以使用单个表达式替换它:

构建一个自定义数组,该数组将遵循您设置的规则

该实现将使用一个简单的1d连续数组。您将需要一个函数,该函数将返回给定行的数组开头。大概是这样的:

int* Get( int* array , int n , int row )   //might contain logical errors
{
    int pos = 0 ;
    while( row-- )
    {
        pos += n ;
        n /= 2 ;
    }

    return array + pos ;
}
其中
n
与您描述的n相同,并且在每次迭代中向下舍入

每整行只需调用此函数一次


这个函数永远不会花费超过O(logn)的时间,但是如果您愿意,可以用一个表达式替换它:

这个表达式没有硬性的答案。如果您的算法需要的内存比您预期的要多,那么您需要找到一个可能较慢但符合您的约束条件的内存


除此之外,唯一的选择是实现两者,然后比较它们的性能。如果节省内存会导致10%的速度降低,您的使用是否可以接受?如果使用更多内存的版本速度快50%,但只在最大的计算机上运行,它会被使用吗?这些是我们在计算机科学中必须解决的问题。但你只有在有了数字后才能看它们。否则,你们只是在猜测,在相当长的时间里,我们的直觉在优化方面是不正确的。

这个问题并没有确切的答案。如果您的算法需要的内存比您预期的要多,那么您需要找到一个可能较慢但符合您的约束条件的内存


除此之外,唯一的选择是实现两者,然后比较它们的性能。如果节省内存会导致10%的速度降低,您的使用是否可以接受?如果使用更多内存的版本速度快50%,但只在最大的计算机上运行,它会被使用吗?这些是我们在计算机科学中必须解决的问题。但你只有在有了数字后才能看它们。否则,你们只是在猜测,我们在优化方面的直觉在相当长的时间内是不正确的。

“我正在努力在两种优化之间做出决定”-最好的方法是同时实现这两种优化,然后根据你们的目标来衡量哪一种更快/消耗更少的内存。@yes,在这种情况下,这肯定会解决问题,但我以前从未遇到过这种问题,我想知道是否有关于内存优化与性能的见解,这可能更有用注意,您可以预先分配大小为2n的一维数组(因为n+n/2+n/4+…收敛到2n)。根据我的经验,在优化中根本没有“固定的”规则/指导原则-最终,您将始终需要使用具体的数据和算法进行度量。对于一个问题可能有效的方法对于另一个问题可能完全错误。有一个很好的答案涉及到配对函数,它似乎已经消失。“我正在努力在两个优化之间做出决定”-最好的方法是同时实现这两个优化,然后根据您的目标衡量哪一个更快/消耗更少内存。@是的,在这种情况下,这肯定会解决问题,但我以前从未遇到过这种问题,我想知道是否有关于内存优化与性能的见解,这可能更有用注意,您可以预先分配大小为2n的一维数组(因为n+n/2+n/4+…收敛到2n)。根据我的经验,在优化中根本没有“固定的”规则/指导原则-最终,您将始终需要使用具体的数据和算法进行度量。对于一个问题可能有效的方法对于另一个问题可能完全错误。有一个很好的答案涉及到配对函数,它似乎已经消失。感谢添加几何级数链接,我要提到这一点。感谢添加几何级数链接,我要提到这一点。