Память, сопоставляющая массив другому массиву в C - PullRequest
0 голосов
/ 03 мая 2020

Я работаю с al oop с очень большим количеством итераций, и поэтому код внутри него будет весьма критичным по производительности. В какой-то момент в l oop я беру ранее заполненный массив значений типа double и передаю его функции, которую для наших целей мы можем рассматривать просто как функцию суммы, то есть, поскольку ей необходимо l oop для каждого элемента в массиве и объединить его в стоимость.

Затем позже мне нужно взять этот первый массив и снова передать его той же функции, но с измененным последним элементом. Непосредственный подход, который приходит на ум, состоит в том, чтобы скопировать первые n-1 элементов в новый буфер, а затем установить этот последний элемент по мере необходимости. Тем не менее, я чувствую, что в большом l oop это было бы неэффективно, поэтому я думал о способах минимизировать эти издержки.

В частности, мне интересно, можно ли было бы использовать mmap для отображения первых n-1 элементов нашего второго буфера на первые n-1 элементов исходного буфера, а затем изменить последний, неотображенный элемент по мере необходимости. Это должно быть в состоянии работать с использованием копирования при записи, поэтому, хотя второй буфер выделен, копирование данных фактически не происходит (очевидно, пока второй буфер только читается). Затем я смог бы передать этот второй буфер той же функции, которая будет прозрачно воздействовать на него без какого-либо знания отображения, преобразования адресов до n-1 в первый буфер и n-го адреса, фактически находящегося во втором буфере. ,

Я пытался собрать воедино некоторый код, чтобы посмотреть, можно ли это сделать и работать так, как ожидалось, но сейчас моя главная проблема заключается в том, что mmap отображает только массивы в дескрипторы файлов, а не массивы в массивы.

Мои вопросы:

  1. Можно ли добиться такого поведения, используя mmap?
  2. Как я могу реализовать это, не используя файловые дескрипторы, и если мне нужно использовать их, как лучше это сделать?

Я также упомяну, что было бы лучше, если бы решение оставалось полностью прозрачным для функции, которой передаются эти буферы, из-за того, как эта база кода предназначен для использования.

1 Ответ

1 голос
/ 03 мая 2020

mmap не подходит для этого. И это на самом деле не нужно.

При повторном вызове функции суммы:

  1. сохранить значение последнего элемента
  2. установить последний элемент на измененное значение
  3. вызов функции суммы
  4. восстановление значения последнего элемента из его сохраненного значения

Вот некоторый код, который иллюстрирует то, что я имею в виду:

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 во второй раз, обрабатывая массив whole , просто для замены последнего элемента. Это было бы особенно верно, если иметь дело с большими массивами данных.

Казалось бы, гораздо быстрее получить результат первого вызова суммы и просто применить исправление к результату, основанное на разнице исходное значение последнего элемента и измененное.

Альтернативой может быть вызов функции с массивом, но сокращение счетчика на 1. Затем вызовите его [в третий раз] с указателем на временный массив, который имеет единственный элемент измененного входного значения. Затем объедините два последних возвращаемых значения.

...