noexcept 关键字
在TensorRT8中,关于API的修改中非常的一点是所有 API 都添加了 noexcept
关键字。该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化[1]。 首先,如果编译器知道函数不会抛出异常有助于简化调用该函数的代码;其次,编译器还会对函数本身进行某些特殊的优化操作,这些优化可能不适用于可能出错的代码。
但是编译器不会检查函数是否真的noexecpt
,如果在运行时,noexecpt
函数违反承诺,向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会调用std::terminate()
[2]函数,该函数内部会调用std::abort()
终止程序,以此确保不在运行时抛出异常的承诺。
如 enqueue
在TRT8[3]中被修改为:
virtual int32_t nvinfer1::IPluginV2::enqueue (int32_t batchSize, void const *const *inputs, void *const *outputs, void *workspace, cudaStream_t stream) noexcept=0
在TRT7.2[4]:中该API为:
virtual int32_t nvinfer1::IPluginV2::enqueue (int32_t batchSize, const void *const *inputs, void **outputs, void *workspace, cudaStream_t stream)=0
关于noexcept
关键字的使用,NVIDIA官方在ReleaseNote[5]里这样说:
- TensorRT now declares API’s with the noexcept keyword to clarify that exceptions must not cross the library boundary. All TensorRT classes that an application inherits from (such as
IGpuAllocator
,IPluginV2
, etc…) must guarantee that methods called by TensorRT do not throw uncaught exceptions, or the behavior is undefined.- All API's have been marked as noexcept where appropriate. The
IErrorRecorder
interface has been fully integrated into the API for error reporting. The Logger is only used as a fallback when theErrorRecorder
is not provided by the user.- Callback changes are now marked noexcept, therefore, implementations must also be marked noexcept. TensorRT has never catered to exceptions thrown by callbacks, but this is now captured in the API.
(⊙o⊙)… 也就说任何继承TensorRT类的应用,在被TensorRT调用时必须保证不会抛出未捕获的异常,或者行为未定义,必须在其内部完成异常处理。
noexcept与虚函数
如果一个虚函数适用noexcept
关键字其不会抛出异常,则后续派生出来的虚函数也必须做出同样的承诺;如果,基类的虚函数允许抛出异常,则派生类的对应函数既可以允许抛出异常,也可以不允许抛出异常(对函数本身做更严格的限定)。