0

我在 CUDA 计算能力 2.0 中遇到了 sin 和 cos 的问题。在为 CUDA 计算能力 1.x 编译代码时,它不会出现。我做了一个简单的代码。我在 GeForce GTX 550 Ti 和 GeForce GTX 480 上对其进行了测试,两者都必须得到相同的结果。这是代码:

#include <cufft.h>
#include <stdio.h>
#include "cuda.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#pragma once 
#ifdef __INTELLISENSE__
void __syncthreads();
void atomicAdd(int*, int);
#endif

    __global__ void cuftFrequency(float* in_data, float* out_data, int N, int M, int fromM = 1)
{
    cuComplex s; 
    float t = 0; 
    for (int I = threadIdx.x + blockIdx.x * blockDim.x + fromM; I <= M; I += blockDim.x * gridDim.x)
    {
        s.x = 0;
        s.y = 0; 
        for (int J = 0; J < N; J++)
        {
            t = (6.0 * (J - N / 2)) / I;
            s.x += in_data[J] * cos(t);
            s.y += in_data[J] * sin(t);
        }
/************************* if no problem, array return values 500, else - same refuse
        out_data[I - fromM] = 500;//s.x * s.x + s.y * s.y;
    }
}

extern "C" __declspec(dllexport)    void cuftColorQualifierExec(float* data, float *spm, int N, int M, int fromM)
{   
    float* in_data_dev;
    float *furie_dev;

    cudaDeviceProp prop;
    int N_Dev;
    memset(&prop, 0, sizeof(cudaDeviceProp));
    prop.major = 2;
    prop.minor = 0;
    prop.maxThreadsPerBlock = M - fromM;
    cudaChooseDevice(&N_Dev, &prop);
    cudaSetDevice(N_Dev);
    cudaGetDeviceProperties(&prop, N_Dev);
    int N_thread = 576;
    int N_block = 2;
    int *Count_dev;

    cudaError_t err = cudaMalloc((void**)&in_data_dev, sizeof(float) * N);
    if (err != cudaSuccess)
        fprintf(stderr, "ERROR \"%s:%d\n", cudaGetErrorString(err), __FILE__, __LINE__);

    err = cudaMemcpy(in_data_dev, data, sizeof(float) * N, cudaMemcpyHostToDevice);
    if (err != cudaSuccess)
        fprintf(stderr, "ERROR \"%s:%d\n", cudaGetErrorString(err), __FILE__, __LINE__);

    err = cudaMalloc((void**)&furie_dev, sizeof(float) * (M - fromM + 1));
    if (err != cudaSuccess)
        fprintf(stderr, "ERROR \"%s:%d\n", cudaGetErrorString(err), __FILE__, __LINE__);

    cuftFrequency<<<N_block, N_thread>>>(in_data_dev, furie_dev, N, M, fromM); 

    err = cudaDeviceSynchronize();
    if (err != cudaSuccess)
        fprintf(stderr, "ERROR \"%s:%d\n", cudaGetErrorString(err), __FILE__, __LINE__);

    err = cudaMemcpy(spm, furie_dev, sizeof(float) * (M - fromM + 1), cudaMemcpyDeviceToHost);
    if (err != cudaSuccess)
        fprintf(stderr, "ERROR \"%s:%d\n", cudaGetErrorString(err), __FILE__, __LINE__);

    err = cudaFree(furie_dev);
    if (err != cudaSuccess)
        fprintf(stderr, "ERROR \"%s:%d\n", cudaGetErrorString(err), __FILE__, __LINE__);
}

int main()
{
    int M = 1024, fromM = 1, N = 4000;
    float* data = new float[4000];
    float* spm = new float[M - fromM + 1];

    for (int I = 0; I < N; I++)
        data[I] = cos(6.0 * I);

    for (int I = 0; I < M - fromM + 1; I++)
        spm[I] = 0;

    cuftColorQualifierExec(data, spm, N, M, fromM);

    for (int I = 0; I < M - fromM + 1; I++)
        fprintf(stdout, "%d: %f\n", I, spm[I]);

    return 0;
}

当线程数超过 576 时,此代码不起作用,并且不返回错误。我专门为数组元素设置了 400 值,以说服自己程序达到了这一点。当程序返回正确的值时,请更改它并重新测试。

为什么当我使用计算能力 1.x 编译此代码时,它可以正常工作,但在计算能力 2.0 时它不能正常工作?

4

1 回答 1

1

每个块可以运行多少个线程存在硬件限制。GPU 架构之间的限制因素不同,包括可用寄存器的数量、可用的共享内存和每个 MP 上每个块的最大线程数。您可以使用 CUDA 附带的 CUDA 占用计算器确定您的 GPU 和应用程序的限制因素。

于 2013-09-10T16:58:42.597 回答