首页 文章

连续内存分配的好处

提问于
浏览
3

在性能方面,为矩阵分配连续内存块与单独内存块有什么好处?即,而不是像这样编写代码:

char **matrix = malloc(sizeof(char *) * 50);
for(i = 0; i < 50; i++)
    matrix[i] = malloc(50);

给我50个不同的50个字节的块和一个50个指针的块,如果我改为写:

char **matrix = malloc(sizeof(char *) * 50 + 50 * 50);
char *data = matrix + sizeof(char *) * 50;
for(i = 0; i < 50; i++) {
    matrix[i] = data;
    data += 50;
}

给我一个连续的数据块,有什么好处?避免缓存未命中是我唯一能想到的,甚至只有少量数据(小到足以容纳缓存),对吧?我已经在一个小应用程序上测试了这个,并注意到一个小的加速,并想知道为什么 .

2 回答

  • 3

    这很复杂 - 你需要衡量 .

    使用中间指针而不是计算二维数组中的地址很可能是当前处理器的损失,并且您的两个示例都是这样做的 .

    接下来,适合L1缓存的一切都是一个巨大的胜利 . malloc()最有可能四舍五入到64字节的倍数 . 180 x 180 = 32,400字节可能适合L1缓存,而单个malloc可能分配180 x 192 = 34,560字节可能不适合,特别是如果你添加另外180个指针 .

    一个连续的数组意味着您知道数据如何适合缓存行,并且您知道在硬件中您将拥有最少数量的页表查找 . 拥有数百个mallocs,无法保证 .

  • 0

    在Youtube上观看Scott Meyers的“CPU Caches和Why you care”演示 . 性能提升可以是整个数量级 .

    https://www.youtube.com/watch?v=WDIkqP4JbkE

    至于上面的讨论,中间指针参数很久以前就已经死了 . 编译器将它们优化掉 . N维数组被分配为平坦的1D向量,总是如此 . 如果你执行std :: vector>,那么你可能得到一个有序的向量前向列表,但对于原始数组,它们总是以平面方式分配为一个长的,连续的条带,并且多维访问减少了指针算法与1维访问的方式相同 .

    要访问数组[i] [j] [k](假设{A,B,C}的宽度,高度,深度),可以将i *(BC)(jC)k添加到数组前面的地址 . 无论如何,您必须以一维表示手动进行此数学运算 .

相关问题