使用 mmap 分配双二维数组
Using mmap to allocate double 2D array
我正在尝试使用 mmap create/access twi 不同的 (N+2)*(N+2) 双精度二维数组,以便多个线程可以查看自己的部分并更改它, 应用更改以便所有其他人都能看到。这是我拥有的:
int main(int argc, char *argv[]) {
int N = atoi(argv[1]);
int numProcs = atoi(argv[2]);
int ARRAY_SIZE = (N+2)*(N+2)*sizeof(double);
double **grid = (double **) mmap(NULL, ARRAY_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if (grid == MAP_FAILED) {
printf("Error mmapping grid\n");
}
double **newGrid = (double **) mmap(NULL, ARRAY_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if (newGrid == MAP_FAILED) {
printf("Error mmapping grid\n");
}
当我 运行 它或尝试访问其中的任何内容时,我遇到了分段错误。我也尝试分配内存,使用:
for(i = 0; i < N+2; i++) {
for(j = 0; j < N+2; j++) {
grid[i][j] = malloc(sizeof(double));
}
}
for(i = 0; i < N+2; i++) {
for(j = 0; j < N+2; j++) {
newGrid[i][j] = malloc(sizeof(double));
}
}
但我遇到了:错误:从不兼容的类型 'void *' 分配给 'double'
newGrid[i][j] = malloc(sizeof(double));
我想我在这里遗漏了一些关于 mmap 工作原理的东西,有人能指出我正确的方向吗?
数组或数组的数组是连续的内存区域。使用指向指针的指针的“二维数组”是不连续的。
让我们看一些 "images" 进行比较:
正确的数组数组在内存中看起来像这样:
+--------------+--------------+-----+----------------+--------------+-----+------------------+
| matrix[0][0] | matrix[0][1] | ... | matrix[0][N-1] | matrix[1][0] | ... | matrix[M-1][N-1] |
+--------------+--------------+-----+----------------+--------------+-----+------------------+
另一方面,使用指针到指针的矩阵看起来像这样:
+-----------+-----------+-----------+-----+
| matrix[0] | matrix[1] | matrix[2] | ... |
+-----------+-----------+-----------+-----+
| | |
| | V
| | +--------------+--------------+-----+
| | | matrix[2][0] | matrix[2][1] | ... |
| | +--------------+--------------+-----+
| |
| V
| +--------------+--------------+-----+
| | matrix[1][0] | matrix[1][1] | ... |
| +--------------+--------------+-----+
|
V
+--------------+--------------+-----+
| matrix[0][0] | matrix[0][1] | ... |
+--------------+--------------+-----+
如您所见,它们的内存布局完全不同,这就是为什么您不能将一个用作另一个的原因。
如果 N 是一个编译时常量,或者如果您的编译器支持可变长度数组 (VLA),那么您可以简单地执行以下操作:
double (*grid)[N+2] = (double (*)[N+2]) mmap(NULL, ARRAY_SIZE, ...
grid[4][5] = 2.0; // setting an element
如果N不是常量,你的编译器不支持VLA,那么你需要手动偏移:
double *grid = (double *) mmap(NULL, ARRAY_SIZE, ...
grid[4 * (N + 2) + 5] = 2.0; // setting the same element using manual offsets
我正在尝试使用 mmap create/access twi 不同的 (N+2)*(N+2) 双精度二维数组,以便多个线程可以查看自己的部分并更改它, 应用更改以便所有其他人都能看到。这是我拥有的:
int main(int argc, char *argv[]) {
int N = atoi(argv[1]);
int numProcs = atoi(argv[2]);
int ARRAY_SIZE = (N+2)*(N+2)*sizeof(double);
double **grid = (double **) mmap(NULL, ARRAY_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if (grid == MAP_FAILED) {
printf("Error mmapping grid\n");
}
double **newGrid = (double **) mmap(NULL, ARRAY_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if (newGrid == MAP_FAILED) {
printf("Error mmapping grid\n");
}
当我 运行 它或尝试访问其中的任何内容时,我遇到了分段错误。我也尝试分配内存,使用:
for(i = 0; i < N+2; i++) {
for(j = 0; j < N+2; j++) {
grid[i][j] = malloc(sizeof(double));
}
}
for(i = 0; i < N+2; i++) {
for(j = 0; j < N+2; j++) {
newGrid[i][j] = malloc(sizeof(double));
}
}
但我遇到了:错误:从不兼容的类型 'void *' 分配给 'double' newGrid[i][j] = malloc(sizeof(double));
我想我在这里遗漏了一些关于 mmap 工作原理的东西,有人能指出我正确的方向吗?
数组或数组的数组是连续的内存区域。使用指向指针的指针的“二维数组”是不连续的。
让我们看一些 "images" 进行比较:
正确的数组数组在内存中看起来像这样:
+--------------+--------------+-----+----------------+--------------+-----+------------------+ | matrix[0][0] | matrix[0][1] | ... | matrix[0][N-1] | matrix[1][0] | ... | matrix[M-1][N-1] | +--------------+--------------+-----+----------------+--------------+-----+------------------+
另一方面,使用指针到指针的矩阵看起来像这样:
+-----------+-----------+-----------+-----+ | matrix[0] | matrix[1] | matrix[2] | ... | +-----------+-----------+-----------+-----+ | | | | | V | | +--------------+--------------+-----+ | | | matrix[2][0] | matrix[2][1] | ... | | | +--------------+--------------+-----+ | | | V | +--------------+--------------+-----+ | | matrix[1][0] | matrix[1][1] | ... | | +--------------+--------------+-----+ | V +--------------+--------------+-----+ | matrix[0][0] | matrix[0][1] | ... | +--------------+--------------+-----+
如您所见,它们的内存布局完全不同,这就是为什么您不能将一个用作另一个的原因。
如果 N 是一个编译时常量,或者如果您的编译器支持可变长度数组 (VLA),那么您可以简单地执行以下操作:
double (*grid)[N+2] = (double (*)[N+2]) mmap(NULL, ARRAY_SIZE, ...
grid[4][5] = 2.0; // setting an element
如果N不是常量,你的编译器不支持VLA,那么你需要手动偏移:
double *grid = (double *) mmap(NULL, ARRAY_SIZE, ...
grid[4 * (N + 2) + 5] = 2.0; // setting the same element using manual offsets