Цілком ймовірно, що ця інформація стосується лише обчислювальних можливостей 1.x або cuda 2.0. Більш пізні архітектури та Cuda 3.0 мають більш складний доступ до глобальної пам'яті, і насправді "об'єднані глобальні навантаження" навіть не профілізовані для цих мікросхем.
Крім того, цю логіку можна застосувати до спільної пам'яті, щоб уникнути конфліктів у банках.
Спільна транзакція пам'яті - це така транзакція, при якій усі потоки в напівдеформації одночасно отримують доступ до глобальної пам'яті. Це занадто просто, але правильний спосіб зробити це - просто послідовні потоки отримують доступ до послідовних адрес пам’яті.
Отже, якщо потоки 0, 1, 2 та 3 читають глобальну пам’ять 0x0, 0x4, 0x8 та 0xc, це має бути об’єднане читання.
У прикладі матриці майте на увазі, що ви хочете, щоб ваша матриця зберігалася лінійно в пам'яті. Ви можете робити це як завгодно, і ваш доступ до пам'яті повинен відображати, як викладена ваша матриця. Отже, матриця 3x4 нижче
0 1 2 3
4 5 6 7
8 9 a b
можна робити рядок за рядком, наприклад, так, щоб (r, c) відображалося в пам'яті (r * 4 + c)
0 1 2 3 4 5 6 7 8 9 a b
Припустимо, вам потрібно отримати доступ до елемента один раз і скажімо, що у вас є чотири потоки. Які нитки будуть використані для якого елемента? Можливо, і те, і інше
thread 0: 0, 1, 2
thread 1: 3, 4, 5
thread 2: 6, 7, 8
thread 3: 9, a, b
або
thread 0: 0, 4, 8
thread 1: 1, 5, 9
thread 2: 2, 6, a
thread 3: 3, 7, b
Який краще? Що призведе до злиття читань, а що ні?
У будь-якому випадку, кожна нитка робить три доступу. Давайте розглянемо перший доступ і подивимося, чи потоки послідовно отримують доступ до пам'яті. У першому варіанті перший доступ - 0, 3, 6, 9. Не послідовно, не злитий. Другий варіант, це 0, 1, 2, 3. Послідовно! Злитий! Ага!
Найкращий спосіб - це, мабуть, написати своє ядро, а потім профайлювати його, щоб перевірити, чи є у вас не з’єднані глобальні завантаження та сховища.
thread 0: 0, 1, 2 etc...
), тому я зараз шукаю кращого варіанту :-)