У меня есть ситуация, когда я (возможно) хочу попробовать использовать 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
). Так что, если ответ зависит от реализации, это основные цели, хотя я действительно больше интересуюсь общим ответом, так как я не знаю, на что он будет работать позже.
Я считаю, что было бы безопаснее, если бы вы не пытались изменить буфер под реализацией 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, и вы можете вернуть эту память только с помощью вызова освобождения этого буфера памяти.
Хотя возможно, что в вашей конкретной реализации это не так, я думаю, что в целом было бы целесообразно опубликовать данные. Таким образом, если ваша базовая система изменится в будущем, вы не увидите ошибку, связанную с этим поведением.
При желании вы можете расширить класс векторов так, чтобы при изменении размеров базовой структуры данных вы могли освобождать и перераспределять данные на устройстве. Я не уверен, насколько это будет сложно, или насколько это повлияет на остальную часть вашей программы.
Ответ на ваш вопрос зависит от того, какие флаги были использованы для создания буфера. Если вы позвоните clCreateBuffer с CL_MEM_ALLOC_HOST_PTR или CL_MEM_COPY_HOST_PTR, то реализация OpenCL уже имеет копию (в случае CL_MEM_ALLOC_HOST_PTR, возможно, — это должно быть для реализаций GPU) содержимого местоположения хоста, которое вы предоставили. Теперь вы можете делать все, что захотите, с указателем хоста, а реализация OpenCL не заботится.
Если, с другой стороны, вы используете CL_MEM_USE_HOST_PTR (что я не думаю, что вы делаете или даже можете из-за того, что это устройство с графическим процессором), то, по всей вероятности, ядро либо вылетит при выполнении, либо выдаст нежелательные результаты (в зависимости от того, что в этом есть). Ещё сейчас).
Надеюсь это поможет!