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句柄,所以该场景不建议用户使用,不仅不会对性能带来增益,反而会带来系统线程调度的开销。