2017-01-06 2 views
0

У меня есть две программы, написанные мной с нуля, одна из которых является интегральным и вторым матрично-матричным умножением. Когда я выполнял обе программы с картами GPU, и я установил глобальный размер 1024, я ожидал, что код ядра будет выполняться 1024 раза, и это было правильно, оно выполнялось столько же раз, сколько я установил для глобального размера, и менял локальный размер не имело значения для вывода результатов и вывода. Тот же код, который я пытался выполнить с процессором, и был потрясен, когда увидел, что функция ядра не выполняется столько же раз, сколько и в глобальном размере. Вот пример из интеграла: global size = 2048, local size = 1, Я ожидаю 2048 выполнение функции ядра, и да, это 2048, , но когда мы имеем глобальный размер = 2048 и локальный размер = 16, тогда он выполняет 256 раз ... Нормально ли это? Почему работа с процессором отличается в openCl, чем с GPU? Я думал, что для пользователей не важно, какое устройство мы используем, тот же код должен работать на разных устройствах одинаково. Я ошибаюсь?OpenCL те же алгоритмы для GPU и CPU, но OpenCl работает по-разному для этих двух устройств

Заранее благодарю за помощь!

+0

Нам нужен [минимальный, совместимый, проверенный пример] (http://stackoverflow.com/help/mcve) проблемы. Поэтому, пожалуйста, напишите какой-то код и как вы его ставите (и с каким драйвером OpenCL и т. Д.). Вообще, драйвер должен гарантировать, что вся сетка выполнена, то есть локальный размер рабочего времени, когда выполняются потоки глобального рабочего размера. – einpoklum

+0

Должен быть неправильный перехват идентификатора глобального потока и идентификатора группы и идентификатора локального потока. Как вы проверяете количество казней? –

+0

@huseyintugrulbuyukisik Я просто добавляю + = 1 к глобальной переменной в код ядра, чтобы узнать, сколько раз выполнялось ядро. – Gzyniu

ответ

0

Использование атомных операций для последовательной работы (или, по крайней мере, не легко-приводимой). Чтобы подсчитать, сколько потоков участвовали, не используйте a[0]+=1;

atomic_add(&a[0],1); 

должны работать или даже лучше

atomic_inc(a) 

где представляет собой целое число без знака подписано не имеет значения.

+0

ОК, да, атомный_inc не работает истребитель. Я имею в виду, что он выполняет свою работу, увеличивая ценность, но это значение отличается от глобального размера в конце. Я не понимаю, у меня есть код, который отлично работает на 1, 2 или даже 8 gpu, но когда я ворвался в CPU (я не забыл изменить аргумент clgetDeviceIds для CL_DEVICE_TYPE_CPU), он действует странно ... разными значениями, чем на графических процессорах. Есть ли что-то другое в работе с процессорами вместо графических процессоров? – Gzyniu

+0

Я исправил проблему с разными результатами, но все же у меня проблема с процессором и графическим процессором, работающим по-разному. Я реализовал интеграл в ядре таким образом: у нас есть int id = get_global_id (0), и даже если мы установим глобальный размер экстремально большой, каждый поток будет выполнять меньшую часть работы, но на CPU я вижу, что если я установил local_size = 4096 (это max) в ядре, у меня есть нити, пронумерованные от 0 до 4095 ... почему?Я получаю глобальный идентификатор, а не локальный ... в GPU он работал, когда локальный размер был установлен в 1 и 1024, и такой проблемы не наблюдалось. Почему это? – Gzyniu

+0

id начинается с 0 –

0

Я узнал об источнике проблемы. Это было из-за плохой точности float, когда я менял переменные, чтобы удвоить, это прекрасно работает. Я где-то читал, что процессор и графический процессор с точки зрения операций с плавающей запятой работают немного иначе по точности.

Смежные вопросы