opencl - кривые руки или библиотека?

Здравствуйте. Программирую на ocl, уже долго мучаюсь с одной проблемой, которую сейчас попытаюсь изложить.

1. создаю контент, инициализирую код и 1 главный буффер, размер которого велик.
2. в каждом потоке, которые являются потоками с серверного сокета, я инициализирую, загружаю, удаляю: свой кёнел, малый буффер.

Таким образом, контент у меня константный, и главный буффер тоже. А в каждом потоке для подсчёта\вывода данных создаётся свой кёнел, и буффер куда он скидывает вычисления\откуда берёт исходные данные.

Итак, суть проблемы: всё хорошо, всё работает отлично, только... При создании буффера, кёнела, ега запуска НЕ ИЗ главного потока, множатся хендлы! Если делать тоже самое из главного потока, то всё окей! Временно вышел из ситуации переводом в главный поток посредством sendmessage.
Однако мне так не нравится делать, и хотелось бы узнать, покрайней мере, где проблема.
Сразу скажу, что дебаг занимает уже не 1 день, и не 2 и не 3. А более 6-ти месяцев. За это время уже обновлялся сам драйвер, но проблема так и не решилась.

Конечно можно не создавать кёнел много раз, как я это делаю, искать выходы на подобии sendmsg и прочего, но есть конкретный ньюанс, и хотелось бы его решить. Кроме того, если либа не потокобезопасная - то пусть так и пишут (это просто мысли вслух).

Значится, amdocl (т.е. от хроноса под АМД).

Буду рад, покрайней мере, любому комментарию на тему потокобезопасности. Может кто сталкивался.

Forums: 

В общем Хронос официально

В общем Хронос официально растолковал, что ocl библиотеки не потокобезопасны. Что, видимо, будет являться конечным вердиктом.

В нормальном виде, id потока, использующего контент, должно быть равно id потока, его создавшего. Иначе утечка.

В смысле, там на стеке

В смысле, там на стеке что-то хранится? Вроде бы, нечему быть на стеке....?

Что будет, если я создам контекст и все прочее (буфера, очереди и т.п.), обложу все это глобальным семафором, а пользоваться буду из нескольких потоков?

Ответ

То будут множаться хендлы, потому что ID потока, из которого идёт вызов, не будет равен ID потока, который создал контент.

Хотите - проверяйте. И дело тут не в критической секции и прочем, а вот именно что в ID потока. Сам уже очень много сил угробил, что бы сделать нормально.

А самое интересное знаете что (повествую всем читателям)? Что есть блокировки буфера, выполнения кёнелов, всё есть. Понятное дело, что иногда удобно ассинхронно удалить за собой уже ненужные объекты, но... Потокобезопасность более нужная вещь, нежели разнообразие в той или иной ассинхронности и т.д.

Вот так вот! Печально, что врядле ситуация изменится. Ибо, как я уже тут упомянул, оффициально протолковано, что "not thread safe" и всё тут.

Если что, я работаю в Win, реализовал сообщениями. Можно сделать свои сообщения, можно выделить специальный трейд и сделать в нём обработку всего необходимого, но... Мороки то! В целом либа хорошая, однако сей факт чуток смутил. Ну, ничё не остаётся, придётся так.

Удачи!

Удивительное дело

Удивительное дело какое-то.

Вот в OpenCL 1.1, в аппендиксе A.2 написано ровно обратное: thread safe.

Надо исследовать....

th?

Значит всё-таки кривые руки? Я как раз 1.1 версию и использую. То, что проблема есть в настоящий момент - это факт, а что касается надписей... Это на одном из форумов, не помню АМД или Хроноса кинули ссылку, нужно копаться что бы найти её и предъявить здесь в качестве доказательства.

С надписями все просто: -

С надписями все просто:
- надпись о thread safety вынесена в "короткий" список отличий OCL 1.1
- ну и аппендикс A.2, где все написано ("за исключением SetKernelArg")

А вот жизнь может оказаться богаче, причем кучей способов:
- у ATI в этом месте проблема, а conformity tests ее не находят
- или, к примеру и банально, в path валяется opencl.dll старой версии....

TH

И так, на всякий случай всё проверил. И даже немного более предложенного. Проблемы всё теже, нашёл ещё одну.

Краткий лист:

1. Во-первых остаётся проблема размножения хендлов, что при длительной работе так же приводит и к утечки памяти. Это происходит, если работа с Command Quene пролегает не из того же потока, из которого мы её инициализируем.

Решение: использование synchronize, а так же WM (windows messages), для передачи управления главному потоку. Так проблема решается.

2. Второй, более страшный баг: если у нас два устройства, и впринципе мы хотим работать с ними в двух различных приложениях, то... Не спешите. Через некоторое время, в ocl-драйвере произойдёт ошибка. От чего она происходит, я лично не разбирался. Можно обложить ассинхронную передачу комманд мьютексами, соответственно это сопроводится несколько процентным спадом производительности.

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

PS срок сбоя драйвера у меня иногда составляет пол дня, однако такой сбой есть.

__
Это всё касается OCL 1.1.

Немного лирики:

"С надписями все просто:" - всё, да не очень просто. На заборе тоже написАно. Например, не хочу показаться грубым, но большенство пользователей OCL в различных средах программирования, и не заметят утекающие помаленьку хендлы в "никуда". Кроме того, если запуск производится "единожды" - это ещё сложнее.

"надпись о thread safety вынесена в "короткий" список отличий OCL 1.1" - вынесена, однако не один я разорался насчёт данных проблем. На англоязычных форумах об этом уже не один пост пИсан.

"у ATI в этом месте проблема, а conformity tests ее не находят" - это не проблема ATI. Это проблема утаревшего подхода к поиску драйвера. Изначально, роутера OpenCl.dll небыло, и приходилось вручную выбирать ocl. В настоящий момент этого не требуется, оттуда и проблема.

"- или, к примеру и банально, в path валяется opencl.dll старой версии...." - как таковой path не требуется, dll валяется в системной Win директории всё время. В случае с ATI, OpenCl.msi установит и удалит всё более, чем правильно. Однако не думаю, что копирование трёх файлов это впринципе большая проблема.

__

Ну вот, вроде, и всё. Надеюсь в OCL 1.2 обстоятельства изменятся.

Ага, спасибо. Практика -

Ага, спасибо.
Практика - критерий истины.

Если у вас образовался компактный тестирующий код (т.е. без вашей специфики) - было бы здорово, если бы он вдруг появился в общедоступности.

КОД

Без проблем, а какой именно код нужен? Тыканье пальцем в утечку?

Ну как-то так. Что-то такое,

Ну как-то так. Что-то такое, что работает, а потом говорит "я испортилось". Уж не знаю, как ему это удастся и удастся ли вообще, но вы то как-то проблему детектировали.

Такой пример надо, естественно, совать во все места (Хронос и их форум, ATI и их форум, если на Интеле есть порча - то и туда).

Да, и кстати если будет

Да, и кстати если будет небольшой test-case, мне не трудно будет его проверить на windows и linux (nvidia), и если проблема обнаружится и у меня, то я могу тоже в саппорт запостить. Скажем так, мне прям сейчас OpenCL не нужен, но в будущем может понадобится - и хотелось бы чтобы проблем поменьше было.

То что у NVidia с их OpenCL

То что у NVidia с их OpenCL 1.0 есть проблемы c thread-safe - это "давно известно", по меньшей мере в форумах про это писали. Ну так в 1.0 и не обещал никто.

У Nvidia - нет, не

У Nvidia - нет, не зарелизили. 1.0 есть во всех новых драйверах, а 1.1 так и остался только в том (258-м, кажется).

Почему оно так - я не знаю, но в технические сложности, которые нельзя было бы решить за год - не верю. Подозреваю какой-то marketing bullshit "если мы поддержим хороший общий OpenCL, то это может убить CUDA".

Подозреваю какой-то marketing

Подозреваю какой-то marketing bullshit
я что-то такое слышал(только не касательно 1.1, а просто об nvidia и opencl).

1. в каждом потоке, которые

1. в каждом потоке, которые являются потоками с серверного сокета, я инициализирую, загружаю, удаляю: свой кёнел, малый буффер.
2. При создании буффера, кёнела, ега запуска НЕ ИЗ главного потока, множатся хендлы!
3. Конечно можно не создавать кёнел много раз, как я это делаю

Проблему у вас в каком случае? Когда вызывается kernel из потока который его не создавал?
И что значит "множатся хэндлы"? Какие хэндлы, как это обнаруживается?

Вот открыл я спецификацию ( http://www.khronos.org/registry/cl/specs/opencl-1.1.pdf#page=368 ), и прям в началае параграфа "A.2 Multiple Host Threads" написано:
"All OpenCL API calls are thread-safe^78 except clSetKernelArg. clSetKernelArg is safe to call from any host thread, and is safe to call re-entrantly so long as concurrent calls operate on different cl_kernel objects. However, the behavior of the cl_kernel object is undefined if clSetKernelArg is called from multiple host threads on the same cl_kernel object at the same time^79"
сноска 79:
"There is an inherent race condition in the design of OpenCL that occurs between setting a kernel argument and using the kernel with clEnqueueNDRangeKernel or clEnqueueTask. Another host thread might change the kernel arguments between when a host thread sets the kernel arguments and then enqueues the kernel, causing the wrong kernel arguments to be enqueued. Rather than attempt to share cl_kernel objects among multiple host threads, applications are strongly encouraged to make additional cl_kernel objects for kernel functions for each host thread."

Это случайно не ваш case?

"Проблему у вас в каком

"Проблему у вас в каком случае? Когда вызывается kernel из потока который его не создавал?"

- Вообще любые действя с OCL 1.1 не из того потока, из которого что-либо созданы приводят к размножению хендлов.

- В их числе даже простое создание буфера.

"И что значит "множатся хэндлы"? Какие хэндлы, как это обнаруживается?"

- Что такое handle в windows можно прочитать, введя в поисковике. Смысл в том, что хоть утеря и небольшая, но память за пару дней непрерывной работы всё-таки подьедается (очень много вычислений).

Ещё одна не менее важная проблема, не относящаяся к мультипоточности - это использование двух устройств.

Использование двух устройств в течении длительного времени приводит к ошибке в драйвере. Думаю опубликовывать "креш тест" будет не очень актуально, ибо врядле кто-то будет пол дня ждать. Ибо закономерность, почему происходит слёт, я не увидел.

С этим же алгоритмом одно устройство работает отлично в течении недель!

И ещё один бажок. Касается AMD ocl 1.1. Если во время GPU вычисления включить mpeg-файл (мпег имеет аппаратную поддержку) - компьютер зависает напроч.

Я конечно понимаю, что если вычисляешь на машине, ролик в серьёзн не будешь включать, но почему так сурово?

- Баг. Хотите - проверьте: запустите любой алгоритм и включите mpeg ролик.

"И что значит "множатся

"И что значит "множатся хэндлы"? Какие хэндлы, как это обнаруживается?"
- Что такое handle в windows можно прочитать, введя в поисковике. Смысл в том, что хоть утеря и небольшая, но память за пару дней непрерывной работы всё-таки подьедается (очень много вычислений).

Что такое хэндлы я знаю. Они могут использоваться не только самой windows.
Как именно вы диагностируете размножаемость хэндлов(в вашем случае как я понял хэндлов windows)?

В общем test case на

В общем test case на размножаемые хэндлы в студию.