Opencl буфер с уже удаленным указателем хоста

У меня есть ситуация, когда я (возможно) хочу попробовать использовать std::vector (или, точнее, его хранилище) в качестве указателя хоста для opencl buffer объект с CL_MEM_USE_HOST_PTR, Это, очевидно, проблемы, если vector изменяется и поэтому перераспределяет свою память. Модификации моего vector находятся на этапах программы, где buffer не используется, поэтому моя идея состоит в том, чтобы проверить, идентичен ли указатель хоста буфера указателю на первый элемент vector и воссоздать буфер, если это не так. Моя проблема в том, что я не смог выяснить, законно ли иметь buffer, для которого указатель хоста уже был освобожден, если buffer не используется

Конечно, я мог бы уничтожить буфер в конце фазы, на которой он используется, однако я заранее не знаю, были ли изменены содержимое и / или длина вектора, и если нет, я бы предпочел сохранить старый буфер, Начиная с afaik, это позволило бы ему оставаться кэшированным на устройстве, уменьшая объем данных, которые необходимо было передать по шине pci-e.

Мой вопрос: Разрешено ли иметь opencl buffer с CL_MEM_USE_HOST_PTR для которого указатель узла уже удален указатель узла, если buffer объект только существует, но не используется в ядре.

Напомним, что в настоящее время я работаю против реализации Opencl от nvidias, используя Tesla 2070 в качестве графического процессора, и программное обеспечение, вероятно, будет перенесено в amd gpus / cpus в ближайшем будущем (последнее является основной причиной использования CL_MEM_USE_HOST_PTR). Так что, если ответ зависит от реализации, это основные цели, хотя я действительно больше интересуюсь общим ответом, так как я не знаю, на что он будет работать позже.

1

Решение

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

vector<int> v(25);
cl_mem buf = clCreateBuffer(.v.data(),.CL_MEM_USE_HOST_PTR,...);
v.resize(1000); //Or some other way of changing the size of the stack
clReleaseMemObject(buf);

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

Согласно некоторым обсуждениям эта тема, следует предположить, что как только вы вызываете clCreateBuffer с CL_MEM_USE_HOST_PTR Отметьте, что вы передали контроль над этой памятью платформе OpenCL, и вы можете вернуть эту память только с помощью вызова освобождения этого буфера памяти.

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

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

1

Другие решения

Ответ на ваш вопрос зависит от того, какие флаги были использованы для создания буфера. Если вы позвоните clCreateBuffer с CL_MEM_ALLOC_HOST_PTR или CL_MEM_COPY_HOST_PTR, то реализация OpenCL уже имеет копию (в случае CL_MEM_ALLOC_HOST_PTR, возможно, — это должно быть для реализаций GPU) содержимого местоположения хоста, которое вы предоставили. Теперь вы можете делать все, что захотите, с указателем хоста, а реализация OpenCL не заботится.

Если, с другой стороны, вы используете CL_MEM_USE_HOST_PTR (что я не думаю, что вы делаете или даже можете из-за того, что это устройство с графическим процессором), то, по всей вероятности, ядро ​​либо вылетит при выполнении, либо выдаст нежелательные результаты (в зависимости от того, что в этом есть). Ещё сейчас).

Надеюсь это поможет!

0

По вопросам рекламы [email protected]