清叉实习心得
- 不要一开始把时间花在验证模块功能上,不同机器和环境有差异,先做总体设计
- 积极和学长交流,获取更多信息(代码设计思路,论文),很多问题会更快解决
技术细节
利用多线程时,一般都先让子线程调用start() ,然后再去调用join(),让主进程等待子进程结束才继续走后续的逻辑。
join会让主进程阻塞,先执行join进来的子线程默认的file_descriptor共享策略使用文件描述符作为共享内存句柄,并且当DataLoader上有太多批次时,这将达到限制,受限于open file数量
1
2
3# 解决,切换到file_system策略
import torch.multiprocessing
torch.multiprocessing.set_sharing_strategy('file_system')消息队列库ZMQ
ZMQ提供进程内(inproc://)、进程间(ipc://)、机器间(tcp://)、广播(pgm://)等四种通信协议。
ZMQ context是线程安全的
torch.distributed.barrier()
- 非主进程,被栅栏阻塞,等待所有进程到达(包括主进程处理完毕)
- 主进程,读取数据并处理,此时所有进程都到达栅栏,达到同步
CPU affinity 是一种调度属性, 它可以将一个进程”绑定” 到一个或一组CPU上.
- 进程通常不会在处理器之间频繁迁移,进程迁移的频率小就意味着产生的负载小。
- 手动地为其分配CPU核,而不会过多地占用CPU0,或是让我们关键进程和一堆别的进程挤在一起,所有设置CPU亲和性可以使某些程序提高性能。
Double Buffer:解决“生产者”,“消费者”供需不一致,防止数据丢失,防止闪烁
分为两组环境 (k/2的env),叠加消除CPU空转
调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束。
share_memory_(),将底层内存移到共享内存中。 如果底层内存已经在共享内存中是将不进行任何操作。在共享内存中的tensor不能调整大小。发送到任何进程不会有拷贝开销。
mutilprocess.Event(),两个状态,指定.wait()时是否会阻塞
mutilprocess.Semaphore(n),允许n个进程进入,信号量机制