内存将数组映射到 C 中的另一个数组
Memory Mapping An Array to Another Array In C
我正在使用一个迭代次数非常多的循环,因此其中的代码对性能非常关键。在循环中的某个时刻,我采用先前填充的双精度数组并将其传递给一个函数,出于我们的目的,我们可以只考虑一个求和函数,因为它需要遍历数组中的每个元素并将其组合成一个值.
然后我需要获取第一个数组并将其再次传递给同一个函数,但最后一个元素已更改。立即想到的方法是将前 n-1 个元素复制到新缓冲区中,然后根据需要设置最后一个元素。但是,我觉得这是一个大循环,效率很低,所以我一直在想办法尽量减少这种开销。
特别是我想知道是否可以使用 mmap
将我们第二个缓冲区的前 n-1 个元素映射到原始缓冲区的前 n-1 个元素,然后更改根据需要最后一个未映射的元素。这应该能够使用写时复制工作,因此尽管分配了第二个缓冲区,但实际上并没有发生任何数据复制(显然只要第二个缓冲区仅被读取)。然后我可以将第二个缓冲区传递给相同的函数,该函数将在不知道映射的情况下透明地作用于它,直到 n-1 的地址转换为第一个缓冲区,而第 n 个地址实际上在第二个缓冲区中.
我试图将一些代码放在一起,看看是否可以完成并按预期工作,但我现在的主要问题是 mmap
仅将数组映射到文件描述符,而不是将数组映射到数组.
那么我的问题是
- 我可以使用
mmap
实现此行为吗?
- 我如何在不使用文件描述符的情况下实现它,如果我必须使用它们,我应该怎么做?
我还要提到,如果解决方案对这些缓冲区传递给的函数保持完全透明,那将是最好的,因为这个代码库是如何使用的。
mmap
不适合这个。而且,它并不是真正需要的。
第二次调用求和函数时:
- 保存最后一个元素值
- 将最后一个元素设置为修改后的值
- 调用求和函数
- 从其保存的值中恢复最后一个元素值
这里有一些代码可以说明我的意思:
double
sumall(double *arr,size_t cnt)
{
double sum = 0;
for (size_t idx = 0; idx < cnt; ++idx)
sum += arr[idx];
return sum;
}
double
sumall_newlast(double *arr,size_t cnt,double newval)
{
double oldval;
double sum;
// save original value of last element
oldval = arr[cnt - 1];
// set new value for last element
arr[cnt - 1] = newval;
sum = sumall(arr,cnt);
// restore original value of last element
arr[cnt - 1] = oldval;
return sum;
}
int
main(void)
{
double arr[1000];
sumall(arr,1000);
sumall_newlast(arr,1000,37.285);
return 0;
}
更新:
我意识到这可能不可能,这取决于实际的算法,但是...
第二次调用求和函数似乎很浪费,处理整个数组,只是为了最后一个元素的变化。如果处理 大 数据数组,则尤其如此。
获取第一个 sum 调用的结果并根据原始最后一个元素值与修改后的元素值的差异对结果进行更正似乎要快得多。
另一种方法可能是使用数组调用该函数,但将计数减 1。然后使用指向临时数组的指针 [第三次] 调用它,该临时数组具有修改后的输入值的单个元素。然后,合并最后两个 return 值。
我正在使用一个迭代次数非常多的循环,因此其中的代码对性能非常关键。在循环中的某个时刻,我采用先前填充的双精度数组并将其传递给一个函数,出于我们的目的,我们可以只考虑一个求和函数,因为它需要遍历数组中的每个元素并将其组合成一个值.
然后我需要获取第一个数组并将其再次传递给同一个函数,但最后一个元素已更改。立即想到的方法是将前 n-1 个元素复制到新缓冲区中,然后根据需要设置最后一个元素。但是,我觉得这是一个大循环,效率很低,所以我一直在想办法尽量减少这种开销。
特别是我想知道是否可以使用 mmap
将我们第二个缓冲区的前 n-1 个元素映射到原始缓冲区的前 n-1 个元素,然后更改根据需要最后一个未映射的元素。这应该能够使用写时复制工作,因此尽管分配了第二个缓冲区,但实际上并没有发生任何数据复制(显然只要第二个缓冲区仅被读取)。然后我可以将第二个缓冲区传递给相同的函数,该函数将在不知道映射的情况下透明地作用于它,直到 n-1 的地址转换为第一个缓冲区,而第 n 个地址实际上在第二个缓冲区中.
我试图将一些代码放在一起,看看是否可以完成并按预期工作,但我现在的主要问题是 mmap
仅将数组映射到文件描述符,而不是将数组映射到数组.
那么我的问题是
- 我可以使用
mmap
实现此行为吗? - 我如何在不使用文件描述符的情况下实现它,如果我必须使用它们,我应该怎么做?
我还要提到,如果解决方案对这些缓冲区传递给的函数保持完全透明,那将是最好的,因为这个代码库是如何使用的。
mmap
不适合这个。而且,它并不是真正需要的。
第二次调用求和函数时:
- 保存最后一个元素值
- 将最后一个元素设置为修改后的值
- 调用求和函数
- 从其保存的值中恢复最后一个元素值
这里有一些代码可以说明我的意思:
double
sumall(double *arr,size_t cnt)
{
double sum = 0;
for (size_t idx = 0; idx < cnt; ++idx)
sum += arr[idx];
return sum;
}
double
sumall_newlast(double *arr,size_t cnt,double newval)
{
double oldval;
double sum;
// save original value of last element
oldval = arr[cnt - 1];
// set new value for last element
arr[cnt - 1] = newval;
sum = sumall(arr,cnt);
// restore original value of last element
arr[cnt - 1] = oldval;
return sum;
}
int
main(void)
{
double arr[1000];
sumall(arr,1000);
sumall_newlast(arr,1000,37.285);
return 0;
}
更新:
我意识到这可能不可能,这取决于实际的算法,但是...
第二次调用求和函数似乎很浪费,处理整个数组,只是为了最后一个元素的变化。如果处理 大 数据数组,则尤其如此。
获取第一个 sum 调用的结果并根据原始最后一个元素值与修改后的元素值的差异对结果进行更正似乎要快得多。
另一种方法可能是使用数组调用该函数,但将计数减 1。然后使用指向临时数组的指针 [第三次] 调用它,该临时数组具有修改后的输入值的单个元素。然后,合并最后两个 return 值。