Как сопоставить записи 2D-матрицы с массивом 1D с помощью косвенного массива указателей?

Примечание. Я отредактировал этот вопрос с учетом полезных отзывов Кита Рэндалла и Чию.

У меня есть идея использовать 1D-массив для кэширования наиболее часто используемых элементов 2D-матрицы NxM в конкретном контексте обработки. Вопрос в том, существует ли уже масса работ, откуда можно получить представление, или есть просто люди, осведомленные. Сначала я расскажу о работе ног, а потом тоже задам вопрос. В качестве дополнительного примечания: Chiyou уже предложил кривые заполнения пробелов, которые концептуально выглядят как то, что мне нужно, но не дают быстрого ответа на мой конкретный вопрос (т.е. я не могу найти кривую, которая чего я добиваюсь).

Легкая работа. В настоящее время наиболее часто используемые записи определяются как комбинация циклов и специального pointer_array (см. код ниже), которые в комбинации создают индексы для наиболее используемые матричные элементы. Массив указателей содержит числа в диапазоне [0, max( N, M)] (см. выше размеры матрицы, определенные как NxM).

Цель кода — создать подходящую (в контексте программы) комбинацию индексов для обработки некоторых элементов матрицы. Возможно N = M, то есть квадратная матрица. Код (C++), проходящий через матрицу, будет выглядеть следующим образом.

for(int i = 0; i < N; i++)
{        
    for(int j = i + 1; j < M; j++)
    {
        auto pointer1 = pointer_array[i];
        auto pointer2 = pointer_array[i + 1];
        auto pointer3 = pointer_array[j];
        auto pointer4 = pointer_array[j + 1];

        auto entry1 = some_matrix[pointer1][pointer3];
        auto entry2 = some_matrix[pointer2][pointer4];
        auto entry3 = some_matrix[pointer3][pointer4];
        auto entry4 = some_matrix[pointer1][pointer2];

        //Computing with the entries...
    }
}

Некоторые вещи, заслуживающие отдельного внимания:

  1. Я думаю, что для того, чтобы это кэширование было целесообразным, оно должно быть плотным. То есть что-то, к чему можно получить доступ случайным образом и что оно расположено в памяти непрерывно. т.е. пространство не «тратится впустую» (за исключением, может быть, если есть много отдельных фрагментов), а сложность находится в O (1). Это означало бы, что кеш не может быть такой же двумерной матрицей, упорядоченной полностью, как одномерный упорядоченный массив строк/столбцов. Я чувствую, что он должен вписываться в массив, имеющий длину max(N, M) (см. выше определение размера матрицы).

  2. Многие записи в some_matrix будут игнорироваться во время циклов.

  3. Порядок pointer_array записывает маршрут по матрице, поэтому он используется и в других местах.

  4. Я сталкивался с этой необходимостью в различных случаях, но на этот раз я написал 2-opt алгоритм доступа к памяти, который я пытаюсь улучшить. Я знаю, что есть другие способы написать алгоритм (но обратите внимание на то, что есть другие настройки, с которыми я столкнулся, и теперь мне интересно, было ли общее решение).

  5. Нестандартным мышлением было бы создание аналогичной комбинации индексов для чего-то, что концептуально похоже на доступ к 2D-матрице, но только более разумно. Одним из вариантов может быть кэширование строк/столбцов матрицы во время цикла.

  6. Поскольку записи будут использоваться много, было бы более идеально заменить косвенность pointer_array кэшированием вызовов some_matrix, чтобы получение значений entry* в циклах было бы быстрее, т.е. из предварительно загруженного кеша вместо, возможно, довольно большого матрица. Другой момент здесь заключается в том, что он будет сохраняться в хранилище, что, в свою очередь, означает, что часто используемые значения могут очень хорошо соответствовать более быстрому кешу.

Вопрос: Можно ли устроить схему индексации так, чтобы матричная индексация по сути стала

//Load the 2D matrix entries to some_1d_cache using the pointer_array
//so that the loop indices can be used directly...

for (int i = 0; i < N; i++)
{        
    for (int j = i + 1; j < M; j++)
    {           
        //The some_1d_cache((x, y) call will calculate an index to the 1D cache array...
        auto entry1 = some_1d_cache(i, j);
        auto entry2 = some_1d_cache(i + 1, j + 1);
        auto entry3 = some_1d_cache(j, j + 1);
        auto entry4 = some_1d_cache(i, i + 1);

        //Computing with the entries...
    }
}

Или, может быть, что-то вроде следующего тоже подойдет

for (int i = 0; i < N; i++)
{        
    for (int j = i + 1; j < M; j++)
    {            
        auto pointer1 = pointer_array[i];
        auto pointer2 = pointer_array[i + 1];
        auto pointer3 = pointer_array[j];
        auto pointer4 = pointer_array[j + 1];

        //The some_1d_cache((x, y) call will calculate an index to the 1D cache array...
        auto entry1 = some_1d_cache(pointer1, pointer3);
        auto entry2 = some_1d_cache(pointer2, pointer4);
        auto entry3 = some_1d_cache(pointer3, pointer4);
        auto entry4 = some_1d_cache(pointer1, pointer2);

        //Computing with the entries...
    }
}

person Veksi    schedule 26.08.2012    source источник
comment
Боюсь, этот вопрос загадочен. Что именно вы пытаетесь кэшировать? Части матрицы? Если да, то какова схема доступа? Понятно, что если я просто пройдусь по всей матрице, кэширование вообще не поможет.   -  person Keith Randall    schedule 27.08.2012
comment
Кит, да, я пытаюсь кэшировать часть матрицы. Часть для кэширования указывается индексами в массиве указателей. Схема доступа описана в циклах.   -  person Veksi    schedule 27.08.2012
comment
Итак, вы пытаетесь кэшировать верхнюю треугольную часть матрицы NxM? Любой из кеша, вы имеете в виду выделить непрерывный кусок памяти?   -  person Keith Randall    schedule 27.08.2012
comment
Да, я стремлюсь выделить непрерывный кусок памяти, в основном моей целью является одномерный массив из-за (в настоящее время воспринимаемой) простоты. Я не пытаюсь кэшировать верхнюю треугольную часть матрицы, но индексы цикла предоставляют индексы для массива указателей, которые, в свою очередь, содержат нужные индексы матрицы. Вызов может быть чем-то вроде some_matrix[0][10] и some_matrix[10][0] во время одного и того же запуска. Я отредактирую вопрос об этом (и исправлю там ошибку условия индекса).   -  person Veksi    schedule 28.08.2012
comment
Извините, я сдаюсь. Я до сих пор не понимаю, в чем смысл всего этого. Может быть, написать цикл для того, что вы пытаетесь сделать с помощью простой разметки строк? Или это ваш первый фрагмент кода? Но тогда почему ваш первый фрагмент кода не просто выполняет auto entry1 = some_matrix[i][j]? Какой смысл в pointer_array? Это псевдонимы записей в одном и том же хранилище?   -  person Keith Randall    schedule 28.08.2012
comment
Кейт, я отредактировал вопрос, чтобы сделать его более ясным. Без обид, это, я мог бы быть яснее. Я также начинаю думать, что это не так просто решить проблему.   -  person Veksi    schedule 28.08.2012


Ответы (1)


Вы можете индексировать 2D-матрицу с помощью кривой заполнения 1D-пространства. Математически это H(x,y) = (h(x) * h(y)). Они также полезны, потому что они в основном подразделяются, хранят некоторую информацию о местоположении и переупорядочивают плоскость.

person Gigamegs    schedule 27.08.2012
comment
Эй, Чию, это полезный указатель, определенно что-то, что можно использовать в поисковых системах. Я рассмотрю этот ход мыслей более внимательно в течение недели. - person Veksi; 27.08.2012