

https://github.com/triton-inference-server/model_analyzer/blob/main/qa/L0_multi_model_profile/test.sh

https://docs.nvidia.com/deeplearning/triton-inference-server/archives/tensorrt_inference_server_090_beta/tensorrt-inference-server-guide/docs/architecture.html


+ 3 模型单线程（3 stream）串行推理 

+ 3 模型3线程（3 stream）并行推理   



+ 几个概念

mutex   
当我在工作中进行激烈的讨论时，我会在办公桌上放一只橡皮鸡，专门用于这种场合。拿着鸡的人是唯一被允许说话的人。如果你不抓鸡，你就不会说话。你只能表明你想要鸡，直到等你拿到鸡再说话。演讲结束后，您可以将鸡交还给主持人，主持人将把鸡交给下一位发言者。这确保了人们不会互相交谈，也有自己的谈话空间。    
用互斥体替换Chicken，用线程替换person，你基本上就有了互斥体的概念。    
用于通过确保关键代码段内的互斥来保护共享资源。  
 
-----------------     

semaphore 
把信号量想象成夜总会的保镖。一次允许一定数量的人进入俱乐部。如果俱乐部已满，则不允许任何人进入，但一旦一个人离开，另一个人可能会进入。      
这只是限制特定资源的消费者数量的一种方法。例如，限制对应用程序中数据库的同时调用次数。  
某种意义上，互斥体是信号量的特例 （二进制信号量相同） [diff](https://stackoverflow.com/questions/62814/difference-between-binary-semaphore-and-mutex/346678#346678)   
信号量的正确使用是用于从一个任务向另一个任务发送信号。互斥意味着每个使用它所保护的共享资源的任务都会按照这个顺序获取和释放互斥体。相比之下，使用信号量的任务要么发出信号，要么等待，而不是两者兼而有之。例如，任务1可能包含在按下“电源”按钮时发布（即信号或增量）特定信号量的代码，而唤醒显示器的任务2则挂在同一信号量上。在这种情况下，一个任务是事件信号的生产者；另一个是消费者。   

--------  
lock   
锁只允许一个线程进入被锁定的部分，并且该锁不与任何其他进程共享，锁必须由获取它的同一线程释放。一些锁可以由同一线程多次获取而不会导致死锁，但必须释放相同的次数。

互斥体与锁相同，但它可以是系统范围的（由多个进程共享）。   
信号量允许x个线程进入，这可以用来限制同时运行的cpu、io或ram密集型任务的数量。    
信号量可以由一个线程获取，并由另一个线程释放，这在普通锁中是不可能的。  
您还可以使用读/写锁，在任何给定时间允许无限数量的读取器或1个写入器。



--------------------

https://github.com/NVIDIA/ProViz-AI-Samples/blob/master/onnxruntime_cpp_samples/cuda_provider/src/NVIDIAInference.cpp    
https://developer.nvidia.com/zh-cn/blog/end-to-end-ai-for-nvidia-based-pcs-cuda-and-tensorrt-execution-providers-in-onnx-runtime/   


https://eli.thegreenplace.net/2016/c11-threads-affinity-and-hyperthreading/     
https://github.com/eliben/code-for-blog/tree/main/2016/threads-affinity   
