OpenCL межконтекстный псевдоним буфера - PullRequest
1 голос
/ 09 января 2020

Предположим, у меня есть 2 устройства с поддержкой OpenCL на моей машине (не включая процессоры); и предположим, что мой злой коллега создает другой контекст для каждого из них, с которым мне приходится работать.

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

enum { size = 1234 };
//...
context_1 = clCreateContext(NULL, 1, &some_device_id, NULL, NULL, NULL);
context_2 = clCreateContext(NULL, 1, &another_device_id, NULL, NULL, NULL);

void* host_mem = malloc(size);
assert(host_mem != NULL);
buff_1 = clCreateBuffer(context_1, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,  size, host_mem, NULL);
buff_2 = clCreateBuffer(context_2, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,  size, host_mem, NULL);

Я понимаю, что, официально ,

Результат команд OpenCL, которые работают с несколькими объектами буфера, созданными с тем же host_ptr или перекрывающиеся регионы хоста считаются неопределенными.

Но что на самом деле произойдет, если я скопирую в этот буфер с одного устройства и из этого буфера на другое устройство? Я особенно заинтересован в случае (относительно недавних) графических процессоров AMD и NVIDIA.

Ответы [ 2 ]

1 голос
/ 09 января 2020

Если поставщик вашей реализации OpenCL гарантирует какое-то конкретное c поведение, выходящее за рамки стандарта, то go с этим и обязательно следуйте любым инструкциям по ограничению буквы.

Если это нет, тогда вы должны принять то, что говорит стандарт.

0 голосов
/ 14 января 2020

Я знаю, что не могу разделить буферы между контекстами

Проблема не в контекстах. Это платформы. По сути, есть два случая:

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

2) вам нужно разделить буфер между устройствами с разных платформ. В этом случае вы сами по себе.

ожидание "отчета об ошибке с разделенным контекстом для назначения и обработки" никуда вас не приведет, потому что, если это контексты с той же платформы, они будут скажу вам, что я сказал в 1), и если это контексты с разных платформ, они скажут вам, что невозможно поддерживать каким-либо вменяемым способом.

«что на самом деле произойдет» ... зависит (от гаджиллона вещи). Некоторые платформы пытаются сопоставить указатель памяти (если он правильно выровнен, для некоторого определения «правильно») с адресным пространством устройства. Некоторые платформы просто тихо копируют его в память устройства. Некоторые платформы также обновляют содержимое памяти хоста после каждой команды в очереди (что может означать значительное замедление), в то время как другие обновляют ее только в определенных c «точках синхронизации».

Мой личный опыт заключается в том, чтобы избегать CL_MEM_USE_HOST_PTR, если только я не знаю, что я работаю с iGPU или реализацией процессора (и правильно настроил указатели).

Если у вас есть AMD и NVIDIA gpus на одной машине, я Я не знаю ни одного официального способа, которым они могут эффективно делиться буферами, что означает, что вам все равно придется go через память хоста ... в этом случае я бы избегал любых игр с CL_MEM_USE_HOST_PTR и просто полагался на clMap / Unmap или clRead / запись.

...