注意
Go to the end to download the full example code
CPU 最佳实践
本章重点介绍环境设置的最佳实践,以在CPU上进行训练和推理时获得最佳性能。
英特尔
超线程技术
对于特定的工作负载,如GNN领域,建议的默认设置以获得最佳性能是关闭超线程。关闭超线程功能可以在BIOS [1] 或操作系统级别 [2] [3] 完成。
替代内存分配器
替代的内存分配器,如tcmalloc,可能通过更高效的内存使用提供显著的性能改进,减少不必要的内存分配或释放的开销。tcmalloc使用线程本地缓存来减少线程同步的开销,通过使用自旋锁和每个线程的竞技场分别减少锁争用,并按大小分类内存分配以减少内存碎片化的开销。
为了利用tcmalloc提供的优化,请在您的系统上安装它(在Ubuntu上,tcmalloc包含在libgoogle-perftools4包中),并将共享库添加到LD_PRELOAD环境变量中:
export LD_PRELOAD=/lib/x86_64-linux-gnu/libtcmalloc.so.4:$LD_PRELOAD
OpenMP 设置
由于OpenMP是默认的并行后端,我们可以通过dgl.utils.set_num_threads()来控制性能,包括采样和训练。
如果未设置OpenMP线程数且数据加载器中的num_workers设置为0,OpenMP运行时通常会默认使用可用的CPU核心数。这在大多数情况下效果良好,也是DGL中的默认行为。
如果数据加载器中的num_workers设置为大于0,每个工作进程的OpenMP线程数将被设置为1。这是PyTorch中的默认行为。在这种情况下,我们可以将OpenMP线程数设置为主进程中的CPU核心数。
性能调优高度依赖于工作负载和硬件配置。我们建议用户尝试不同的设置,并选择最适合自己情况的设置。
数据加载器 CPU 亲和性
注意
此功能仅适用于dgl.dataloading.DataLoader。目前尚不适用于dgl.graphbolt中的dataloaders。
如果数据加载器的工作线程数大于0,请考虑使用DGL数据加载器类的use_cpu_affinity()方法,这通常会显著提高训练性能。
use_cpu_affinity 将设置适当的 OpenMP 线程数(等于为主进程分配的 CPU 核心数), 将数据加载器工作线程绑定到单独的 CPU 核心,并将主进程限制在剩余的 CPU 核心上。
在多NUMA节点设置中,use_cpu_affinity默认只会使用NUMA节点0的核心,假设工作负载在多个NUMA节点之间扩展效果不佳。如果您认为您的工作负载在利用多个NUMA节点时会有更好的性能,您可以传递用于数据加载(loader_cores)和计算(compute_cores)的核心列表。
loader_cores 和 compute_cores 参数(CPU核心列表)可以传递给 enable_cpu_affinity,以便更好地控制应使用哪些核心,例如在工作负载在多个NUMA节点上扩展良好的情况下。
- Usage:
dataloader = dgl.dataloading.DataLoader(...) ... with dataloader.enable_cpu_affinity(): <training loop or inferencing>
手动控制
有关OpenMP设置的高级和更细粒度控制,请参阅[4]文章《在CPU上最大化Intel® PyTorch*优化性能》
脚注
Total running time of the script: (0 minutes 0.000 seconds)