我正在处理一个迭代次数非常高的循环,因此其中的代码将对性能相当关键。在循环的某一点上,我把一个之前填充的双数组传递给一个函数,对于我们的目的来说,我们可以认为它只是一个和函数,即它需要循环处理数组中的每个元素,并将其组合成一个值。
那么以后我需要把这第一个数组再传给同一个函数,但是最后一个元素发生了变化。我想到的直接方法是将前n-1个元素复制到一个新的缓冲区中,然后根据需要设置这最后一个元素。然而,我觉得由于这是在一个大的循环中,这将是低效率的,所以我一直在思考如何将这个开销最小化。
特别是我想知道是否可以使用 mmap
将第二个缓冲区的前n-1个元素映射到原始缓冲区的前n-1个元素上,然后根据需要改变最后一个未映射的元素。这应该能够使用copy-on-write工作,所以虽然分配了第二个缓冲区,但实际上并没有发生任何数据复制(显然只要第二个缓冲区只是读)。然后,我可以将第二个缓冲区传递给同一个函数,该函数将在不知道任何映射的情况下透明地对其进行操作,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;
}
UPDATE:
我意识到 可 不可能,这取决于实际算法,但......。
第二次调用求和函数,再处理一下 全部 数组,只是为了改变最后一个元素。如果处理的是 大型 数据数组。
取第一次调用的结果,然后根据原始的最后一个元素值和修改后的元素值的差值对结果进行修正,这样似乎会快得多。
一个替代方法可能是用数组调用函数,但将计数缩短为1,然后用一个指向临时数组的指针调用函数[第三次],这个临时数组有修改后的输入值的单个元素。然后,合并最后两个返回值。