Context管理
原理介绍
在LXHPL中,Context是用户进程中所有资源的载体,用户应用想要正常运行,必须在程序开始时预先创建Context。单个进程内部,Context与Device对应,用户调度多个Device,就需要为每个Device创建Context。
单线程单Context
用户可以从LynSDK提供的示例代码中查看完整样例,在示例代码中,调用各接口后都添加了异常判断和处理,以下是关键步骤代码示例,仅供参考,不可以直接拷贝编译。
lynError_t err = 0;
lynContext_t context = nullptr;
const int EVENT_COUNT = 10;
lynEvent_t eventList[EVENT_COUNT] = {nullptr};
int i;
err = lynCreateContext(&context, 0);
for (i = 0; i < EVENT_COUNT; i++) {
err = lynCreateEvent(&eventList[i]);
}
//销毁资源
for (i = 0; i < EVENT_COUNT; i++) {
err = lynDestroyEvent(&eventList[i]);
}
lynDestroyContext(context);
单线程多Context
当用户在单线程中基于多个Device创建多个Context,默认以最后一次创建的Context为当前线程的Context。当用户想要在当前线程内切换Context时,可以调用lynSetCurrentContext进行切换,切换后当前线程的后续任务将会在切换后的Context所对应的Device上下发。
备注
在单线程内做Context切换后,需要为目标Device创建新的Stream(如果目标Device没有创建过Stream),而不能基于源Device上的Stream进行任务下发。
用户可以从LynSDK提供的示例代码中查看完整样例,在示例代码中,调用各接口后都添加了异常判断和处理,以下是关键步骤代码示例,仅供参考,不可以直接拷贝编译。
int32_t devID0 = 0;
int32_t devID1 = 1;
lynContext_t ctx0 = nullptr;
lynContext_t ctx1 = nullptr;
lynStream_t stream0 = nullptr;
lynStream_t stream1 = nullptr;
//为每个Device创建Context
lynCreateContext(&ctx0, devID0);
lynCreateContext(&ctx1, devID1);
lynCreateStream(&stream0);
//下发异步任务……(默认在Device 1上执行)
//同步等待Stream结束
lynSynchronizeStream(stream0);
//切换至ctx0(即切换至Device 0)
lynSetCurrentContext(ctx0);
//需要为ctx0创建新Stream,否则后续异步任务还会在Device 1上进行
lynCreateStream(&stream1);
//下发异步任务……(切换到Device 0上执行)
//同步等待Stream结束
lynSynchronizeStream(stream1);
//销毁资源
lynDestroyStream(stream0);
lynDestroyStream(stream1);
lynDestroyContext(ctx0);
lynDestroyContext(ctx1);
多线程多Context
多线程场景一般是调度多Device,用户可以在每个线程中调度一个Device,为该Device创建Context和Stream,并在相应的Device上下发异步任务。用户可以从LynSDK提供的示例代码中查看完整样例,在示例代码中,调用各接口后都添加了异常判断和处理,以下是关键步骤代码示例,仅供参考,不可以直接拷贝编译。
bool ctx_create_destroy_test(int32_t device)
{
lynError_t err = 0;
lynContext_t ctx0;
int32_t devID = device;
err |= lynCreateContext(&ctx0, devID);
err |= lynDestroyContext(ctx0);
return true;
}
bool ctx_create_destroy_test_multithread()
{
lynError_t err0 = 0;
lynError_t err1 = 0;
lynError_t err2 = 0;
//创建多个线程,并基于每个Device创建Context
std::future<bool> fur0 = std::async(std::launch::async, ctx_create_destroy_test, 0);
std::future<bool> fur1 = std::async(std::launch::async, ctx_create_destroy_test, 1);
std::future<bool> fur2 = std::async(std::launch::async, ctx_create_destroy_test, 2);
err0 |= fur0.get();
err1 |= fur1.get();
err2 |= fur2.get();
return true;
}
多线程单Context
多线程单Context场景下,单Context是基于特定Device创建的,由于Context是与Device绑定的,所以即使多线程创建,拿到的也是同一个Context句柄,所以该场景不建议用户使用,不仅不会对性能带来增益,反而会带来系统线程调度的开销。