Информация об изменениях

Сообщение Re[3]: Очень быстрое заполнение матрицы (массива) от 26.01.2024 13:51

Изменено 26.01.2024 13:58 Maniacal

Re[3]: Очень быстрое заполнение матрицы (массива)
Здравствуйте, Pzz, Вы писали:

Pzz>Это не промахи кэша. В названии RAM, Random Access Memory, слово Random является большим преувеличением. Современная память в разы (если не на порядки) работает быстрее при последовательном доступе, чем при произвольном. И это не только на уровне интерфейса между процессором и памятью (там, где влияет кэш), это и сама память так устроена.


У Мыщьха в какой-то книге или статье есть огромная глава про это (про переключение страниц памяти). Тут главное последовательно матрицу в памяти заполнять. А то на запись ячейки памяти уходит условно два такта процессора, а на переключение 4KB страницы, вроде, что-то около 20000+

Вот фрагмент из его книги "Техника оптимизации программ. Эффективное использование памяти", тут оптимизаторы подсказали. Эксперименты с большими массивами у него в третьей главе, с наскока полный текст первой главы нашёл.

Какие многомерные массивы? Какие кэш-промахи? Здесь у нас и близко нет ни того, ни другого! Судя по всему, мы столкнулись с грубой ошибкой Инструктора (шаблонный поиск дает о себе знать!), но все же не поленимся, и заглянем в предлагаемый Инструктором пример, памятуя о том, что всегда в первую очередь следует искать ошибку у себя, а не у окружающих. Быть может, это мы чего-то недопонимаем:

Original Code                         Optimized Code
int b[200][120];                      int b[200][120];
void xmpl17(int *a)                   void ympl17(int *a)
{                                     {
    int i, j;                            int i, j;
    for (i = 0; i < 120; i++)            int atemp;
        for (j = 0; j < 200; j++)        for (j = 0; j < 200; j++)
                                             for (i = 0; i < 120;i++)
    b[j][i]=b[j][i]+a[2*j];
}                                        b[j][i]=b[j][i]+a[2*j];
                                      }

Ну вот, все правильно. Приводимый профилировщиком VTune фрагмент кода наглядно демонстрирует, что двухмерные массивы лучше обрабатывать по строкам, а не столбцам (см. "Часть III. Подсистема кэш-памяти"). Но ведь у нас нет двухмерных массивов, а, стало быть, и слушаться Инструктора в данном случае не надо.

Re[3]: Очень быстрое заполнение матрицы (массива)
Здравствуйте, Pzz, Вы писали:

Pzz>Это не промахи кэша. В названии RAM, Random Access Memory, слово Random является большим преувеличением. Современная память в разы (если не на порядки) работает быстрее при последовательном доступе, чем при произвольном. И это не только на уровне интерфейса между процессором и памятью (там, где влияет кэш), это и сама память так устроена.


У Мыщьха в какой-то книге или статье есть огромная глава про это (про переключение страниц памяти). Тут главное последовательно матрицу в памяти заполнять. А то на запись ячейки памяти уходит условно два такта процессора, а на переключение 4KB страницы, вроде, что-то около 20000+

Вот фрагмент из его книги "Техника оптимизации программ. Эффективное использование памяти", тут оптимизаторы подсказали. Эксперименты с большими массивами у него в третьей главе, с наскока полный текст первой главы нашёл.

Какие многомерные массивы? Какие кэш-промахи? Здесь у нас и близко нет ни того, ни другого! Судя по всему, мы столкнулись с грубой ошибкой Инструктора (шаблонный поиск дает о себе знать!), но все же не поленимся, и заглянем в предлагаемый Инструктором пример, памятуя о том, что всегда в первую очередь следует искать ошибку у себя, а не у окружающих. Быть может, это мы чего-то недопонимаем:

Original Code                         Optimized Code
int b[200][120];                      int b[200][120];
void xmpl17(int *a)                   void ympl17(int *a)
{                                     {
    int i, j;                            int i, j;
    for (i = 0; i < 120; i++)            int atemp;
        for (j = 0; j < 200; j++)        for (j = 0; j < 200; j++)
                                             for (i = 0; i < 120;i++)
    b[j][i]=b[j][i]+a[2*j];
}                                        b[j][i]=b[j][i]+a[2*j];
                                      }

Ну вот, все правильно. Приводимый профилировщиком VTune фрагмент кода наглядно демонстрирует, что двухмерные массивы лучше обрабатывать по строкам, а не столбцам (см. "Часть III. Подсистема кэш-памяти"). Но ведь у нас нет двухмерных массивов, а, стало быть, и слушаться Инструктора в данном случае не надо.


UPD.
Нашёл, я её в своё время скачал в полном виде.