CUDA 提供了许多用于并行计算和 GPU 编程的函数和 API。以下是一些 CUDA 编程中常用的函数:
cudaMalloc(): 用于在 GPU 上动态分配内存。
cudaMemcpy(): 用于在 GPU 和 CPU 之间复制数据。
cudaMemset(): 用于将 GPU 内存中的字节设置为特定值。
cudaThreadSynchronize(): 用于同步当前线程块的所有线程。
cudaDeviceSynchronize(): 用于同步所有 GPU 操作。
cudaEventCreate(): 用于创建事件,用于测量 GPU 操作的时间。
cudaEventRecord(): 用于记录事件。
cudaEventSynchronize(): 用于等待事件完成。
cudaSetDevice(): 用于设置当前使用的 GPU 设备。
cudaGetDevice(): 用于获取当前使用的 GPU 设备。
cudaGetDeviceCount(): 用于获取可用的 GPU 设备数量。
cudaChooseDevice(): 根据指定的设备属性选择一个设备。
cudaSetStream(): 用于设置当前线程的执行流。
cudaStreamCreate(): 用于创建执行流。
cudaStreamDestroy(): 用于销毁执行流。
cudaStreamSynchronize(): 用于等待执行流中的所有操作完成。
cudaEventDestroy(): 用于销毁事件。
cudaEventElapsedTime(): 用于计算两个事件之间的时间差。
cudaDeviceReset(): 重置当前 GPU 设备,释放所有未释放的 GPU 资源。
cudaDeviceGetAttribute(): 获取指定设备的属性值。
cudaDeviceGetCount(): 获取可用的 GPU 设备数量。
cudaGetDeviceProperties(): 获取指定设备的属性。
cudaGetLastError(): 获取最后一次 CUDA API 调用的错误码。
cudaGetSymbolAddress(): 获取符号的内存地址。
cudaGetSymbolSize(): 获取符号的大小。
cudaBindTextureToArray(): 将纹理绑定到数组上。
cudaBindSurfaceToArray(): 将表面绑定到数组上。
cudaUnbindTexture(): 解绑纹理。
cudaFreeArray(): 释放数组内存。
cudaFree(): 释放已分配的 GPU 内存。
cudaMalloc()
用于在 GPU 上动态分配内存。这个函数是 CUDA 运行时 API 的一部分,允许开发者在 GPU 上创建一块连续的内存空间,用于存储数据。
cudaMalloc 的原型如下:
cudaError_t cudaMalloc(void **devPtr, size_t size);
参数说明:
devPtr:指向已分配内存的指针的指针。这个指针将在函数调用成功后被设置为新分配内存的起始地址。
size:要分配的字节数。
这是一个简单的示例,展示如何使用 cudaMalloc 在 GPU 上分配内存:
#include <cuda_runtime.h>
#include <stdio.h>
int main() {
// 分配 GPU 内存
size_t size = 10 * sizeof(float); // 假设要分配 10 个浮点数的空间
float *d_array; // GPU 内存指针
cudaError_t err = cudaMalloc(&d_array, size);
if (err != cudaSuccess) {
printf("Error: %s\n", cudaGetErrorString(err));
return -1;
}
// ... 在 GPU 上进行一些计算 ...
// 释放 GPU 内存
cudaFree(d_array);
return 0;
}
使用 cudaMalloc 时,要确保分配的大小不会超过 GPU 的可用内存。如果分配失败,cudaMalloc 将返回一个错误代码,可以通过 cudaGetErrorString 函数获取错误信息。
cudaMemcpy()
用于在 GPU(图形处理器)和 CPU 之间复制数据。这个函数是 CUDA 运行时 API 的一部分,用于执行设备内存到主机内存、主机内存到设备内存或设备内存到设备内存之间的数据传输。
cudaMemcpy 的原型如下:
void cudaMemcpy(void *dest, const void *src, size_t count, cudaMemcpyKind kind);
参数说明:
dest:指向目标内存区域的指针,即数据传输的目的地。
src:指向源内存区域的指针,即数据传输的来源。
count:要复制的字节数。
kind:指定了数据传输的方向,可以是以下几种之一:cudaMemcpyHostToHost、cudaMemcpyHostToDevice、cudaMemcpyDeviceToHost 或 cudaMemcpyDeviceToDevice。
这是一个简单的示例,展示如何使用 cudaMemcpy 从 GPU 复制数据到 CPU:
#include <cuda_runtime.h>
#include <stdio.h>
int main() {
// 假设已经分配了 GPU 内存和 CPU 内存
float *d_array; // GPU 内存
float *h_array; // CPU 内存
// 分配 GPU 内存并将数据从 CPU 复制到 GPU
size_t size = 10 * sizeof(float); // 假设有 10 个浮点数
cudaMalloc(&d_array, size);
cudaMemcpy(d_array, h_array, size, cudaMemcpyHostToDevice);
// ... 在 GPU 上进行一些计算 ...
// 将数据从 GPU 复制回 CPU
cudaMemcpy(h_array, d_array, size, cudaMemcpyDeviceToHost);
// ... 处理数据 ...
// 释放 GPU 内存
cudaFree(d_array);
return 0;
}
使用 cudaMemcpy 时,要确保目标或源指针是有效的,并且复制的字节数不会超过内存限制。此外,要注意同步操作以确保数据传输完成后再进行后续操作。
cudaMemset()
用于将 GPU 内存中的字节设置为特定的值。这个函数是 CUDA 运行时 API 的一部分,用于执行设备内存的初始化操作。
cudaMemset 的原型如下:
void cudaMemset(void *devPtr, int value, size_t count);
参数说明:
devPtr:指向要设置的 GPU 内存的指针。
value:要设置的值。
count:要设置的字节数。
这是一个简单的示例,展示如何使用 cudaMemset 将 GPU 内存中的字节设置为特定的值:
#include <cuda_runtime.h>
#include <stdio.h>
int main() {
// 分配 GPU 内存
size_t size = 10 * sizeof(float); // 假设有 10 个浮点数
float *d_array;
cudaMalloc(&d_array, size);
// 将 GPU 内存中的字节设置为特定值(例如,0)
cudaMemset(d_array, 0, size);
// ... 在 GPU 上进行一些计算 ...
// 释放 GPU 内存
cudaFree(d_array);
return 0;
}
使用 cudaMemset 时,要确保目标指针是有效的 GPU 内存指针,并且要设置的字节数不会超过内存限制。