CUDA,使用memset(或fill或...)设置float到max val的数组

时间:2011-07-26 20:10:10

标签: c++ cuda

编辑:感谢以前的答案。但事实上我想在CUDA中做到这一点,显然CUDA没有功能填充。我必须为每个线程填充一次矩阵,所以我想确保我使用最快的方式。这个for循环是我最好的选择吗?

我想将float的矩阵设置为可能的最大值(在float中)。做这项工作的正确方法是什么?

float *matrix=new float[N*N];

for (int i=0;i<N*N;i++){
        matrix[i*N+j]=999999;
}

提前致谢。

7 个答案:

答案 0 :(得分:17)

CUDA中最简单的方法是使用thrust::fill。 CUDA 4.0及更高版本中包含了Thrust,如果您使用的是CUDA 3.2,则可以install it

#include <thrust/fill.h>
#include <thrust/device_vector.h>
...
thrust::device_vector<float> v(N*N);
thrust::fill(v.begin(), v.end(), std::numeric_limits<float>::max()); // or 999999.f if you prefer

您还可以编写如下的纯CUDA代码:

template <typename T>
__global__ void initMatrix(T *matrix, int width, int height, T val) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;

    for (int i = idx; i < width * height; i += gridDim.x * blockDim.x) {
        matrix[i]=val;
    }
}

int main(void) {
    float *matrix = 0;
    cudaMalloc((void*)&matrix, N*N * sizeof(float));

    int blockSize = 256;
    int numBlocks = (N*N + blockSize - 1) / (N*N);
    initMatrix<<<numBlocks, blockSize>>>(matrix, N, N, 
                                         std::numeric_limits<float>::max()); // or 999999.f if you prefer
}

答案 1 :(得分:4)

你需要遍历数组并在float中将每个std::numeric_limits<float>::max()元素设置为limits ...你不能使用memset因为它设置了每一个内存缓冲区中的 byte ,而不是像浮点数等多字节值到特定值。

因此,您最终会得到如下所示的代码,因为您只为矩阵使用单个数组(即,您不需要第二个for循环):

#include <limits>

float* matrix = new float[N*N];

for (int i=0; i < N*N; i++)
{
    matrix[i] = std::numeric_limits<float>::max();
}

您的请求的第二个巨大问题是memset采用整数类型来设置每个字节的值,因此您必须获得最大浮点值的实际位模式,并将其用作memset的输入。但即使这样也行不通,因为memset只能将内存缓冲区中的每个字节设置为给定值,因此如果将表示浮点值的32位整数值传递给memset,则为只会使用较低的8位...所以最后它不仅仅是我们不建议你去做的事情,但是memset实现的方式是不可能的。您根本无法使用memset将多字节类型的内存缓冲区初始化为特定值,除非您想要将值清零,或者您正在做一些让您编写相同值的奇怪黑客到组成多字节数据类型的所有字节。

答案 2 :(得分:3)

使用std::numeric_limits<float>::max()std::fill作为:

#include <limits>     //for std::numeric_limits<> 
#include <algorithm>  //for std::fill

std::fill(matrix, matrix + N*N, std::numeric_limits<float>::max());

或者,std::fill_n为(看起来更好):

std::fill_n(matrix, N*N, std::numeric_limits<float>::max());

请参阅以下在线文档:

答案 3 :(得分:2)

我建议您轻松完成这项工作,请使用std::fill代替算法标题。

std::fill( matrix, matrix + (N*N), 999999 ) ;

答案 4 :(得分:2)

不要在C ++中使用动态内存,而是使用vector并观察它为您完成所有工作:

std::vector<float> matrix(N * N, std::numeric_limits<float>::max());

事实上,你甚至可以轻松地将它变为二维矩阵:

std::vector<std::vector<float> > matrix(N, std::vector<float>(N, std::numeric_limits<float>::max()));

答案 5 :(得分:1)

C ++方式:

std::fill(matrix, matrix + N*N, std::numeric_limits<float>::max());

答案 6 :(得分:1)

matrix全局内存还是线程本地内存?如果它在全局内存中,并且您只需要初始化(而不是在内核中间重置),那么您可以在启动内核之前使用来自主机的memset。如果它位于内核的中间,请考虑将内核分成两部分,这样你仍然可以使用cudaMemset。

cudaMemset(matrix,std::numeric_limits<float>::max(),N*N*blockSize);