cudaMemcpy 和 cudaMemcpyAsync:
-
cudaMemcpy:
一定阻塞 CPU 线程,直到拷贝完成才返回。 -
cudaMemcpyAsync:
不阻塞 CPU,只把拷贝任务放进某个 CUDA stream 的队列里。
像 CPU 的计算和 IO?
-
CPU:
同步 IO:read() → CPU 等
异步 IO:aio_read() → CPU 继续算 -
CUDA:
cudaMemcpy → CPU 等 GPU
cudaMemcpyAsync → CPU 继续跑
一句话:区别在“调用方等不等”,不是在“干了没干”。
默认流和其他流串行,但其他流之间是并行的:
stream0: |---- memcpy ----|
stream1: |---- kernel ----|
stream2: |---- kernel ----|1️⃣ public NoCopyable —— 为什么禁止拷贝构造?
意义:防止“资源被复制导致双重释放或语义错误”。
Buffer 管理的是底层资源(CPU/GPU 内存指针):
-
拷贝构造会复制:
ptr_(同一块内存地址)allocator_
-
结果可能是:
- 两个对象指向同一块内存
- 析构时 释放两次
- 或谁该释放不清楚(尤其
use_external_)
适用场景:
- GPU/CPU buffer
- 文件句柄
- socket
- mutex
- CUDA stream / event
一句话:
“资源所有权唯一”的对象,必须禁止拷贝。
2️⃣ std::enable_shared_from_this<Buffer> —— 为什么允许 shared?
意义:对象需要在“成员函数内部”安全地把自己交给外部长期持有。
如果没有它:
std::shared_ptr<Buffer> p(this); // ❌ 会导致双重 delete有了它:
auto p = shared_from_this(); // ✅ 引用计数正确shared_from_this() 只能在对象已经由 std::shared_ptr 管理的前提下使用;
std::enable_shared_from_this 的作用是让类在成员函数内部安全地获得指向自身的 shared_ptr(通过内部维护的 weak_ptr 保证引用计数正确),否则直接用 this 构造 shared_ptr 会导致双重释放。
单例工厂模式:
class CPUDeviceAllocatorFactory {
public:
static std::shared_ptr<CPUDeviceAllocator> get_instance() {
if (instance == nullptr) {
instance = std::make_shared<CPUDeviceAllocator>();
}
return instance;
}