cudaMemset() - 它是设置字节还是整数?

12

来自在线文档

cudaError_t cudaMemset (void * devPtr, int value, size_t count )

使用value值填充指向devPtr的内存区域中前count个字节。

参数: devPtr - 指向设备内存的指针 value - 要为指定内存的每个字节设置的值 count - 要设置的字节数

该描述似乎不正确,因为:

int *dJunk;
cudaMalloc((void**)&dJunk, 32*(sizeof(int));
cudaMemset(dJunk, 0x12, 32);

将所有32个整数设置为0x12,而不是0x12121212。(Int vs Byte)

描述涉及设置字节。计数和值以字节为单位描述。注意计数的类型为size_t,值的类型为int。即将一个字节大小设置为一个int值。

cudaMemset()在程序指南中未被提及。 我必须假设我看到的行为是正确的,而文档是错误的。

是否存在更好的文档来源?(在哪里?)
是否支持其他类型?即float *dJunk;有效吗?其他的?

1个回答

23
文档是正确的,你对于 cudaMemset 的理解是错误的。该函数确实设置字节值。你的示例将前 32 个 字节 设置为 0x12,而不是将所有 32 个整数设置为 0x12,即:
#include <cstdio>

int main(void)
{
    const int n = 32;
    const size_t sz = size_t(n) * sizeof(int);
    int *dJunk;
    cudaMalloc((void**)&dJunk, sz);
    cudaMemset(dJunk, 0, sz);
    cudaMemset(dJunk, 0x12, 32);

    int *Junk = new int[n];

    cudaMemcpy(Junk, dJunk, sz, cudaMemcpyDeviceToHost);

    for(int i=0; i<n; i++) {
        fprintf(stdout, "%d %x\n", i, Junk[i]);
    }

    cudaDeviceReset();
    return 0;
}

产生

$ nvcc memset.cu 
$ ./a.out 

0 12121212
1 12121212
2 12121212
3 12121212
4 12121212
5 12121212
6 12121212
7 12121212
8 0
9 0
10 0
11 0
12 0
13 0
14 0
15 0
16 0
17 0
18 0
19 0
20 0
21 0
22 0
23 0
24 0
25 0
26 0
27 0
28 0
29 0
30 0
31 0

例如,所有的128个字节都设置为0,然后前32个字节设置为0x12。完全按照文档所描述的方式。


1
是的,我之前看我的结果时有误。尝试将cudaMemset(dJunk, 0x12, 32);更改为cudaMemset(dJunk, 0x1234, 32);。似乎cudaError_t cudaMemset (void * devPtr, int value, size_t count )应该是:cudaError_t cudaMemset (void * devPtr, char value, size_t count ),即VALUE的大小为字节。使用大小int有点误导人。(只是指出这一点。) - Doug
@Doug:我仍然不确定你的观点是什么。你在问题中引用的文档清楚地说明value被视为字节值。该函数的行为与标准的C memset完全相同,唯一的区别是字节值传递在32位字的LSB中。顺便说一句,如果这正是你真正想要的,驱动程序API中有一个真正的32位memset函数。 - talonmies
如果数据类型是float而不是int,则此方法无效。在这种情况下,Junk始终是一个零数组。如何使其适用于浮点值? - dizcza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接