Как сохранить память в массиве, множество элементов которого всегда равно 0? - PullRequest
0 голосов
/ 06 июля 2018

У меня есть 2tensor в C, который выглядит так:

int n =4;
int l =5;
int p =6;
int q=2;

Затем я инициализирую каждый элемент T

//loop over each of the above indices
T[n][l][p][q]=...

Однако, многие из них равны нулю, и есть симметрии, такие как.

T[4][3][2][1]=-T[3][4][2][1]
  1. Как я могу сохранить память на элементах T, которые равны нулю? В идеале я хотел бы поместить что-то вроде NULL в эти позиции, чтобы они использовали 0 вместо 8 байтов. Кроме того, позже в вычислении я могу проверить, равны ли они нулю или нет, проверив, равны ли они NULL
  2. Как неявно включить эти симметрии в T с использованием избыточной памяти?

Редактировать: симметрия может быть исправлена ​​с помощью другой реализации. Но как насчет нулей? Есть ли реализация, чтобы не тратить их впустую память?

1 Ответ

0 голосов
/ 06 июля 2018

Вы не можете влиять на размер любой переменной значением, которое вы записываете в нее.
Если вы хотите сохранить память, вы должны не только не использовать ее, но и не определять переменную с ее помощью.
Если вы не определили переменную, вы не должны использовать ее никогда.
Тогда вы сохранили память.
Это, конечно, очевидно.

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

У меня большой массив в C (не очень большой, скажем, N записей, с N == 20).
Но по особым причинам мне никогда не понадобится фактически читать и записывать какие-либо четные индексы, они должны вести себя так, как будто они содержат 0, но я хочу сохранить используемую ими память.
Так что на самом деле я хочу использовать только M записей, с M * 2 == N.

Так что вместо

int Array[N]; /* all the theoretical elements */

Я определяю

int Array[M]; /* only the actually used elements */

Конечно, я не могу получить доступ ни к одному из элементов, которые не нужны, и это не будет действительно необходимо.
Но для логики моей программы я хочу иметь возможность программировать так, как если бы я мог получить к ним доступ, но будьте уверены, что они всегда будут только читать 0 и игнорировать любое записанное значение.

Итак, я делаю обертку всех обращений к массиву.

int GetArray(int index)
{
    if (index & 1)
    {
        /* odd, I need to really access the array,
           but at a calculated index */
        return Array[index/2];
    } else
    {
        /* even, always 0 */
        return 0;
    }
}

void SetArray(int index, int value)
{
    if (index & 1)
    {
        /* odd, I need to really access the array,
           but at a calculated index */ */
        Array[index/2] = value;
    } else
    {
        /* even, no need to store anything, stays always "0" */
    }
}

Так что я могу читать и писать так, как если бы массив был в два раза больше, но гарантирую, что никогда не использовать поддельные элементы.
И сопоставляя индексы как
actualindex = wantindex / 2
Я гарантирую, что у меня нет доступа за пределы размера фактически существующего массива.

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

Я рекомендую расширить GetArray () и SetArray () путем проверки результирующего индекса, чтобы убедиться, что он никогда не выходит за пределы фактического массива.
Вы также можете добавить все виды самопроверок, чтобы убедиться, что все ваши правила и ожидания оправданы.

...