Обмениваться большими постоянными данными среди потоков CUDA - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть ядро, которое вызывается несколько раз. При каждом вызове постоянные данные размером около 240 кбайт будут передаваться и обрабатываться потоками. Потоки работают независимо, как функция карты. Время остановки потоков значительно. Причиной этого может быть банковский конфликт чтения памяти. Как я могу справиться с этим? (У меня GTX 1080 ti)

Может ли "const global" из opencl справиться с этим? (потому что постоянная память в cuda ограничена 64 кб)

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

В CUDA я считаю, что лучшей рекомендацией будет использование так называемого кэша «только для чтения». Это имеет как минимум два возможных преимущества по сравнению с системой __constant__ память / постоянный кеш:

  1. Не ограничивается 64 КБ, как __constant__ Память.
  2. Он не ожидает и не требует «единообразного доступа», как это делает константный кеш, для обеспечения полной пропускной способности доступа / наилучшей производительности. Равномерный доступ относится к идее, что все потоки в деформации получают доступ к одному и тому же местоположению или одному и тому же постоянному значению памяти (за цикл чтения / инструкцию).

Кэш только для чтения описан в Руководстве по программированию CUDA . Возможно, самый простой способ его использования - украсить ваши указатели , переданные ядру CUDA, с помощью __restrict__ (при условии, что вы не совмещаете указатели ) и украсить указатель, который ссылается на большие постоянные данные с const ... __restrict__. Это позволит компилятору генерировать соответствующие инструкции LDG для доступа к постоянным данным, вытягивая их через механизм кэширования только для чтения.

Этот механизм кэширования только для чтения поддерживается только на графических процессорах cc 3.5 или выше, но он охватывает некоторые графические процессоры поколения Kepler и все графические процессоры Maxwell, Pascal (включая GTX 1080 ti), Volta и Turing.

Если у вас графический процессор меньше чем cc3.5, возможно, лучшее предложение для аналогичных преимуществ (больше, чем __const__, не требующее единообразного доступа) тогда будет использовать текстурную память. Это также задокументировано в другом месте в руководстве по программированию, есть различные примеры кодов CUDA, которые демонстрируют использование памяти текстур, и множество вопросов здесь по тегу SO cuda, охватывающему это.

0 голосов
/ 05 ноября 2018

Постоянная память, которая не помещается в аппаратный постоянный буфер, обычно «проливается» на global память в OpenCL. Однако банковские конфликты обычно являются проблемой с local памятью, так что это, вероятно, не так. Я предполагаю, что постоянный лимит CUDA в 64 кБ отражает аппаратное обеспечение nvidia, поэтому OpenCL не будет волшебно работать лучше здесь.

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

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

  • Сократите объем постоянных / глобальных данных, которые вам нужны, например, используя более эффективные типы, другие механизмы сжатия или вычисляя некоторые значения на лету (возможно, сохраняя их в памяти local для всех потоков в группе). поделиться).
  • Кластерирует наиболее часто используемые данные в небольшом буфере constant и явно помещает наиболее редко используемые константы в global буфере. Это может помочь среде выполнения более эффективно размещать ее на оборудовании. Если это не поможет, попробуйте скопировать часто используемые данные в local память и сделать ваши группы потоков большими и сравнительно длительными, чтобы скрыть попадание при копировании.
  • Проверьте, можно ли улучшить занятость потока. Обычно это возможно, и это приводит к значительному улучшению производительности практически в любой ситуации. (кроме случаев, когда ваш код уже сильно привязан к ALU / FPU)
...