Страницы

Поиск по вопросам

Показаны сообщения с ярлыком cuda. Показать все сообщения
Показаны сообщения с ярлыком cuda. Показать все сообщения

понедельник, 13 апреля 2020 г.

CUDA: Ошибка при компиляции программы

#c #cuda #cpp

                    
Доброго времени суток!
Прошу помочь. Компиляция программы не проходит из-за ошибок типа "identifier is undefined
in device code".  Пояснение по программе: есть реализация AES от Брайена Гладмана (Brian
Gladman, Worcester, UK), которую я хочу использовать в своей cuda-программе.  Ошибка,
мешающая компиляции, возникает при использовании макроса в коде Брайена. Например,
в строчке:
ke8(cx->ks, 0); ke8(cx->ks, 1);

ke8 - это макрос, его код:
#define ke8(k,i) \
{ kef8(k,i); \
    k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
    k[8*(i)+13] = ss[5] ^= ss[4]; \
    k[8*(i)+14] = ss[6] ^= ss[5]; \
    k[8*(i)+15] = ss[7] ^= ss[6]; \
}

Насколько я понял, такая ошибка связана с макросами, и во время компиляции он не
определяется cuda-устройством. Хотя, буквально 2-мя строчками выше "ke8(cx->ks, i);"
работает без нареканий, а ведь там тоже работает тот же самый макрос. Гугль-поиск решения
этой проблемы не дал.
Из-за чего может возникать ошибка "identifier is undefined in device code", и как
её решить?    


Ответы

Ответ 1



Ошибка identifier is undefined in device code возникает в том случае, если идентификатор не определен. Поскольку, глядя на макрос, трудно сказать, во что он раскрывается, рекомендуется посмотреть на файл, полученный из исходника препроцессором. Для этого в C/C++/Preprocessor, выставить Generate Preprocessed File в YES. После компиляции посмотреть на код, оставшийся от макроса, и обратить внимание на те переменные, которые трактуются как необъявленные. Если их реально нет, значит, что-то не подключено (библиотека или заголовок).

Ответ 2



Вам нужно добавить директиву препроцессора GPU, в противном случае фиксированные поисковые таблици не определены в памяти устройства, а в памяти хоста и CUDA не может их найти.

понедельник, 2 марта 2020 г.

Какую лучше архитектуру использовать для вычислений на GPU

#cpp #cuda #gpu #opencl


Необходимо перенести вычисления с CPU на GPU. Начал гуглить про это всё, в итоге
есть 2 похожие архитектуры - CUDA от Nvidia и OpenCL от AMD, второе можно и на Nvidia
использовать. Вроде бы пишут, что видеокарты на AMD больше заточены под вычисления
и быстрее на 30-40%.

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

Программу пишу на C#, но как понял, класс вычислений придется писать на C++ и подключать
библиотеку к своей программе.
    


Ответы

Ответ 1



Занимаюсь сложными гидродинамическими расчётами на GPU уже давно - OpenCL. По производительности вычислений float карты NVidia всегда опережают AMD с аналогичным количеством и частотой потоковых процессоров. Процентов на 30-50. От использования double лучше по возможности уходить.

пятница, 24 января 2020 г.

Будет ли CUDA код работать на других видеокартах?

#cuda


Будет ли программа, использующая технологию CUDA работать в системах на видеокартах
NVidia, не поддерживающих CUDA ? А в системах на видеокартах других производителей?    


Ответы

Ответ 1



Смотря как написана программа. В норме - не будет.

Ответ 2



Можно компилировать и запускать программу в режиме эмуляции, т.е. на CPU. Но работать будет, естественно, на порядок медленнее.

понедельник, 23 декабря 2019 г.

Суммирование всех элементов с помощью GPU

#cpp #cuda


Здравствуйте! Не давно познакомился с CUDA, пишу маленькую программу для сравнения
скорости на GPU и CPU. Ядро должно суммировать все элементы, но суммирует только последний
элемент. В чем проблема? Может синхронизация нужна?

#include 
#include "device_launch_parameters.h"
#include 
#include 

using namespace std;
__global__ void add(int *matr, int N, int *sum)
{
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    //if (idx> > (matr_d, N, sum_d);

    cudaMemcpy(sum_h, sum_d, sizeof(int), cudaMemcpyDeviceToHost);
    cout << "sum: " << sum_h[0] << endl;

    free(matr_h);
    cudaFree(matr_d);
    system("pause");
}

    


Ответы

Ответ 1



Проблема в том, что у вас код if (idx

Ответ 2



@Владимир Мартьянов прав. Во первых, для решения задачи внешними источниками, нужны версии CUDA, SM, COMPUTE.Есть простой до безобразия способ. Создайте символ __shared__, и атомарно аккумулируйте значение. Потом просто с хоста мапте значение MapToSymbol. Но тогда бессмысленно параллелить вычисления.Второй способ, более сложный и требует понимания архитектуры CUDA. Смысл описан здесь: CUDA :: Memory Fence Functions.

вторник, 10 декабря 2019 г.

Возможно ли решить проблему фрагментации GPU-памяти на CUDA?

#память #cuda #cpp #linux


Добрый день.
Иногда, когда я пытаюсь выделить память, я получаю ошибку "out of memory", хотя функция
cudaMemGetInfo возвращает количество свободной памяти, которое больше того, что я пытаюсь
выделить. Следовательно, проблема во фрагментации. Возможно ее как-то решить? Есть
ли способ разместить элементы массива, под который выделяется память, не один за другим,
а разбить массив на кусочки и разместить их в разных областях памяти? Но при этом чтобы
работать с ним можно было как с целым массивом.    


Ответы

Ответ 1



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

Ответ 2



Вот именно как с целым массивом - сильно сомневаюсь, что такое можно сделать на CUDA'е. В настольных системах есть такой механизм - мепирование страниц, и то, он является скорее побочным продуктом требований масштабируемости систем, поскольку и ОЗУ у них динамическая и механизм подкачки реализуется. На CUDA'е память скорее регистровая, статическая. Это не требует ее виртуального отображения, поэтому мепирование физических страниц на виртуальные там не требуется. Вот именно мепирование и может такое творить: представлять разнородные физические страницы для пользователя в виде последовательной, плоской памяти. Но даже если в какой-то момент память на CUDA'е станет расширяемой, по типу настольных систем, все равно мепирование происходит постранично. Т.е. при распределении таких массивов будут кратные ограничения на число страниц такого массива, в зависимости от размера его элементов, т.е. все равно небольшая, но фрагментация такой памяти будет присутствовать. Альтернативно задачу можно решить с помощью списка массивов: при выделении набора элементов, если не хватает памяти, делим выборку пополам и пытаемся распределить массивы меньшего размера и т.д., пока не будет выделен весь массив.

суббота, 6 июля 2019 г.

CUDA: Ошибка при компиляции программы

Доброго времени суток! Прошу помочь. Компиляция программы не проходит из-за ошибок типа "identifier is undefined in device code". Пояснение по программе: есть реализация AES от Брайена Гладмана (Brian Gladman, Worcester, UK), которую я хочу использовать в своей cuda-программе. Ошибка, мешающая компиляции, возникает при использовании макроса в коде Брайена. Например, в строчке: ke8(cx->ks, 0); ke8(cx->ks, 1); ke8 - это макрос, его код: #define ke8(k,i) \ { kef8(k,i); \ k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \ k[8*(i)+13] = ss[5] ^= ss[4]; \ k[8*(i)+14] = ss[6] ^= ss[5]; \ k[8*(i)+15] = ss[7] ^= ss[6]; \ } Насколько я понял, такая ошибка связана с макросами, и во время компиляции он не определяется cuda-устройством. Хотя, буквально 2-мя строчками выше "ke8(cx->ks, i);" работает без нареканий, а ведь там тоже работает тот же самый макрос. Гугль-поиск решения этой проблемы не дал. Из-за чего может возникать ошибка "identifier is undefined in device code", и как её решить?


Ответ

Ошибка identifier is undefined in device code возникает в том случае, если идентификатор не определен. Поскольку, глядя на макрос, трудно сказать, во что он раскрывается, рекомендуется посмотреть на файл, полученный из исходника препроцессором. Для этого в C/C++/Preprocessor, выставить Generate Preprocessed File в YES. После компиляции посмотреть на код, оставшийся от макроса, и обратить внимание на те переменные, которые трактуются как необъявленные. Если их реально нет, значит, что-то не подключено (библиотека или заголовок).

пятница, 17 мая 2019 г.

Какую лучше архитектуру использовать для вычислений на GPU

Необходимо перенести вычисления с CPU на GPU. Начал гуглить про это всё, в итоге есть 2 похожие архитектуры - CUDA от Nvidia и OpenCL от AMD, второе можно и на Nvidia использовать. Вроде бы пишут, что видеокарты на AMD больше заточены под вычисления и быстрее на 30-40%.
У кого был опыт программирования на подобном. Можете прояснить пожалуйста, что лучше выбрать для себя?
Программу пишу на C#, но как понял, класс вычислений придется писать на C++ и подключать библиотеку к своей программе.


Ответ

Занимаюсь сложными гидродинамическими расчётами на GPU уже давно - OpenCL. По производительности вычислений float карты NVidia всегда опережают AMD с аналогичным количеством и частотой потоковых процессоров. Процентов на 30-50. От использования double лучше по возможности уходить.

суббота, 16 марта 2019 г.

Будет ли CUDA код работать на других видеокартах?

Будет ли программа, использующая технологию CUDA работать в системах на видеокартах NVidia, не поддерживающих CUDA ? А в системах на видеокартах других производителей?


Ответ

Смотря как написана программа. В норме - не будет.