Рядок головний проти основного розміщення матриць стовпця


16

Чи є причина програмування обчислень щільної матриці вибирати макет рядка-основний макет над основним стовпцем?

Я знаю, що залежно від компонування обраної матриці нам потрібно написати відповідний код, щоб ефективно використовувати кеш-пам'ять для швидкісних цілей.

Верхньо-основний макет здається більш природним і простішим (принаймні, для мене). Але основні бібліотеки, такі як LAPACK, написані у Fortran, використовують основний макет стовпця, тому для цього вибір повинен бути певний.


Якщо ми розглянемо обчислення b = A * x з x стовпчиком вектора, для головного рядка A ми можемо використовувати внутрішні продукти векторів, A (i,:) ^ T x, щоб отримати b (i); для головного стовпця нам можуть знадобитися лише скалярні множення векторів, sum_i A (:, i) x (i). Мені здається, головний стовпчик набагато краще! Що ти думаєш?
Хуй Чжан

Привчіть себе до того, як колон-майор. Це легко, коли ви візуалізуєте вектори як стовпці або їх переміщення у вигляді рядків. Це робить візуалізацію множення матриць дуже простою і дозволяє легко стежити за великою кількістю опублікованої математики.
Майк Данлаве

Відповіді:


18

Основна компоновка стовпців - це схема, що використовується Fortran, і саме тому вона використовується в LAPACK та інших бібліотеках.

Взагалі набагато ефективніше з точки зору використання пропускної здатності пам’яті та продуктивності кешу доступ до елементів масиву в тому порядку, в якому вони викладені в пам'яті. Залежно від того, як зберігаються ваші матриці, вам потрібно вибрати алгоритми, які цим скористаються.

внутрішнє зберігання Внутрішнє зберігання основного формату стовпця


11

У вакуумі, не враховуючи жодного існуючого програмного забезпечення, немає причин віддавати перевагу колонці над основним рядком з кодової точки зору. Однак більшість математичної літератури написана таким чином, що групує вектори в матрицю, зберігаючи їх як стовпці замість рядків. Наприклад, коли ви пишете повне власне значення рівняння , XАХ=ХΛХматриця містить усі власні вектори, записані в стовпці. Ти ніколи не бачиш, що це написано інакше (хоча я чую, що статистика схожа на вектори рядків). Тому було природно, що найдавніше програмне забезпечення передбачало основний формат стовпців, так що якщо у вас є матриця, яка є набором векторів, зберігання будь-якого одного вектора є суміжним. Таким чином, я уявляю, що традиція перенесена до наших днів, і якщо ви хочете взаємодіяти зі старшим Fortran, ви хочете скористатися майором колон. Так що майже вся високоефективна чисельна лінійна алгебра робиться в основній колонці.

Причина C - головний рядок, є дещо наслідком синтаксису його масиву; Ви оголошуєте масив 3 рядка на 2 стовпцем як double a[3][2], а пізніші індекси змінюються швидше, ніж попередні індекси, що для 2D масивів робить його рядком основним. Поєднайте це з природним західним порядком читання зліва направо, це робить основний рядок здаватися більш природним.


2
Я думаю, що це погані аргументи. Той факт, що останній показник у "" подвійному a [3] [2] "" змінюється найшвидше, не випадковість - це було чітке дизайнерське рішення точно так само, як і свідоме дизайнерське рішення у Фортран зробіть це навпаки, коли у вас є масив '' 'real (3,2)' ''.
Вольфганг Бангерт

1
Більше того, це неправда, що майже вся високоефективна числова лінійна алгебра є основним стовпчиком. Це все ще може бути справедливо для BLAS та LAPACK, але це зовсім неправда для кожної головної бібліотеки лінійних алгебр, що з’явилася за останні 15 років: наприклад, і PETSc, і Trilinos використовують основні рядкові формати зберігання матричних рядків.
Вольфганг Бангерт

Я знаю, що конвенція С була свідомим рішенням, ймовірно, заснованим на природному порядку читання. Я мав на увазі, що він, ймовірно, не був розроблений з урахуванням числової лінійної алгебри, тому збіг обставин, що це головний рядок. По-друге, я не мав наміру аргументувати за рідкісні матриці, лише щільні. Для рідких, це трохи змішане назад, з обома стислими форматами рядків і стовпців.
Віктор Лю

5
Не заважати точці, але C спочатку був системною мовою, заснованою на попередніх мовах B та BCPL, працює на таких системах, як PDP-11, які спочатку не мали номера з плаваючою комою. Сказати, що вони спроектували це з урахуванням числових даних, - це досить складно.
Віктор Лю

7
Був там і т. Д. Причина, що матриці в C рухаються останнім індексом найшвидше, тому що C не має матриць. Він має вектори векторів, які можна прозоро реалізувати як суцільні блоки пам'яті або як масиви покажчиків на масиви. Зробити порядок індексів сумісним із Фортрансом (я гадаю) навіть не було на радарі Денніса Річі.
Майк Данлаве

2

Порядок наголошення колони здається більш природним. Наприклад, припустимо, якщо ви хочете зберегти фільм для подання зображення за малюнком, тоді ви використовуєте порядок стовпців, і це дуже інтуїтивно, і ніхто не збереже його в порядку основного рядка.

Якщо ви програміст на C / C ++, вам слід використовувати декілька бібліотек вищого рівня для матриць (Eigen, Armadillo, ...) із стовпчиком основного стовпця. Лише маніяк використовував би необроблені вказівники C із порядковим порядком, хоча C / C ++ пропонує щось, що нагадує матричну індексацію.

Для простоти все з порядковим основним порядком слід вважати як мінімум дивним. Фрагмент за шматочком - це просто природний порядок, це означає порядок основного стовпця (як Фортран). Наші батьки / матері мали дуже вагомі причини, чому вони обрали його.

На жаль, до того, як стало зрозуміло, кілька цікавих бібліотек було створено в строковому порядку, ймовірно, через брак досвіду.

Для уточнення нагадування визначення рядкового основного порядку, коли правий індекс змінюється швидше за один крок через пам'ять, наприклад A (x, y, z), це z-індекс, це означає, що в пам'яті пікселі з різних фрагментів суміжні, що ми б не хотіли Не хочу. Для фільму A (x, y, t) останній показник - час t. Не важко уявити, що зберегти фільм у режимі-мажорі просто неможливо.


2

м×н

  • мi,ji×м+j
  • мi,jj×н+i

Тепер уявіть собі такий алгоритм:

for i from 1 to m
   for j from 1 to n
      do something with m(i,j)

i×м+j

Висновки:

  1. так, це має важливе значення, але вибір залежить від способу доступу до даних. У попередньому прикладі, якщо використовується порядок стовпців, то ви можете просто поміняти дві петлі.

  2. правило: швидко змінюється індекс повинен бути відображений в послідовних місцях пам'яті.

  3. що ще важливіше, вимірювання / порівняльний аналіз впливу вибору є основоположним, оскільки це залежить від багатьох параметрів (розмір даних, розмір кеша, те, як використовувана мова відображає декілька індексів на лінійний індекс, спосіб роботи система управляє віртуальною пам'яттю, способи вкладення циклів в бібліотеку лінійних алгебр, яку ви використовуєте ...)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.