工作原理#
当 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操作以及您可能使用的第三方库中的pandas操作。

所有 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统一内存(托管内存)、性能和预取的更多信息,请参阅这篇NVIDIA开发者博客文章。
池分配器提高了分配性能。如果不使用池分配器,内存分配可能会成为瓶颈,具体取决于工作负载。托管内存允许超额订阅GPU内存。这使得cudf.pandas在许多情况下能够处理大于GPU内存的数据,而无需回退到CPU(Pandas)。
注意
在Windows上,特别是Windows子系统Linux(WSL2)上,CUDA托管内存不支持超额订阅,仅支持统一寻址。此外,WSL2上的托管内存具有不理想的性能特征。因此,cudf.pandas在WSL2上使用非托管池分配器,因此cudf.pandas仅限于GPU内存的物理大小。
可以通过更改环境变量 CUDF_PANDAS_RMM_MODE 为以下之一来使用其他内存分配器:
"managed_pool"(默认,如果支持):使用RMM的异步池分配器的CUDA统一内存(托管内存)。"managed": CUDA 统一内存,(托管内存)没有池分配器。"async": CUDA的内置池异步池分配器,使用普通的CUDA设备内存。"pool"(如果"managed_pool"不支持则为默认): RMM的异步池分配器,使用普通的CUDA设备内存。"cuda": 普通的CUDA设备内存,没有池分配器。