Предварительно скомпилированный многомерный доступ к массиву - PullRequest
1 голос
/ 01 июня 2019

Представьте себе вычисление трехмерного массива следующим образом:

for (int i = 0; i < I; i++)
{
    for (int j = 0; j < J; j++)
    {
        for (int k = 0; k < K; k++)
        {
            array[k + j * K + i * K * J] = someValue(i, j, k);
        }
    }
}

Но часть k + j * K + i * K * J довольно дорогая.Можно ли сказать компилятору преобразовать циклы во что-то вроде этого?

array[0] = someValue(0, 0, 0);
array[1] = someValue(0, 0, 1);
array[2] = someValue(0, 0, 2);
array[3] = someValue(0, 1, 0);
...

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

1 Ответ

2 голосов
/ 01 июня 2019

Я полагаю, что в вашем конкретном случае мы можем переписать цикл следующим образом:

auto* scan = array;
for (int i = 0; i < I; i++)
{
    for (int j = 0; j < J; j++)
    {
        for (int k = 0; k < K; k++)
        {
            *scan++ = someValue(i, j, k);
        }
    }
}

Это микрооптимизация, и вам не о чем беспокоиться.Вот почему.

Причина 1: умножение целых чисел невероятно дешево .Вычисление k + j * K + i * K * J дешевле, чем извлечение значения из оперативной памяти компьютера, и это будет примерно так же дешево, как (если не дешевле) извлечение его из самого быстрого кэша ЦП.

Причина 2: Компиляторы невероятно умны.Они могут распознавать, какие значения изменяются, а какие остаются неизменными, и оптимизировать общие подвыражения из циклов (чтобы они не выполняли одно и то же вычисление несколько раз).

Причина 3: Компиляторы могут использовать инструкции векторизации.В зависимости от того, что делает someValue, он может рассчитывать несколько значений параллельно на одном и том же ядре, используя это преимущество.Это верно для любого метода индексации в array.

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

...