工作原理#

激活 cudf.pandas 后,import pandas (或其任何子模块) 将导入一个代理模块,而不是“常规”的 pandas。此代理模块包含代理类型和代理函数。

In [1]: %load_ext cudf.pandas

In [2]: import pandas as pd

In [3]: pd
Out[3]: <module 'pandas' (ModuleAccelerator(fast=cudf, slow=pandas))>

代理类型/函数上的操作尽可能在 GPU 上执行,否则在 CPU 上执行,必要时在底层进行同步。这适用于您的代码和您可能使用的第三方库中的 pandas 操作。

cudf-pandas-execution-flow

所有 cudf.pandas 对象在任何给定时间都是 GPU (cuDF) 或 CPU (pandas) 对象的代理。属性查找和方法调用首先在 GPU 上尝试(必要时从 CPU 复制)。如果失败,则在 CPU 上尝试该操作(必要时从 GPU 复制)。

此外,cudf.pandas 特别处理链式方法调用(例如 .groupby().rolling().apply()),这些调用可能在链中的任何级别失败,并会最小化地回溯和重放链以提供正确的结果。数据仅在必要时自动从主机传输到设备(反之亦然),从而避免不必要的设备-主机传输。

使用 cudf.pandas 时,cuDF 的pandas 兼容模式会自动启用,以确保与 pandas 特定的语义(如默认排序顺序)保持一致。

cudf.pandas 默认使用托管内存池。这使得 cudf.pandas 能够处理大于其运行所在 GPU 内存的数据集。默认情况下也启用了托管内存预取,以提高内存访问性能。有关 CUDA Unified Memory(托管内存)、性能和预取的更多信息,请参阅这篇 NVIDIA Developer 博客文章

内存池分配器提高了分配性能。如果不使用池分配器,内存分配可能会成为性能瓶颈,具体取决于工作负载。托管内存支持 GPU 内存的超额订阅。这使得 cudf.pandas 在许多情况下能够处理大于 GPU 内存的数据,而无需回退到 CPU (Pandas)。

注意

Windows 上的 CUDA Managed Memory,特别是 Windows Subsystem for Linux (WSL2),不支持超额订阅,只支持统一寻址。此外,WSL2 上的托管内存具有不良的性能特性。因此,cudf.pandas 在 WSL2 上使用非托管内存池分配器,所以 cudf.pandas 的限制取决于 GPU 的物理内存大小。

可以通过更改环境变量 CUDF_PANDAS_RMM_MODE 为以下值之一来使用其他内存分配器:

  1. "managed_pool"(默认,如果支持):使用 RMM 异步内存池分配器的 CUDA Unified Memory(托管内存)。

  2. "managed":CUDA Unified Memory(托管内存),不使用内存池分配器。

  3. "async":使用标准 CUDA 设备内存和 CUDA 内置的异步内存池分配器。

  4. "pool"(如果不支持 "managed_pool" 时的默认值):使用标准 CUDA 设备内存和 RMM 的异步内存池分配器。

  5. "cuda":标准 CUDA 设备内存,不使用内存池分配器。