0

私はこのコードを持っていて、1-2回の起動ごとにクラッシュします。malloc / cudaMallocHost / cudeMallocを使用してみましたが、役に立ちませんでした。これは手動のcufftComplexの初期化が原因で発生すると考えられますが、データがないとfftを取得できないため、発生しないことを証明します。このクラッシュを解消するのを手伝ってもらえますか?

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <conio.h>
#include <cuda.h>
#include <cufft.h>

using namespace std;

int main(int argc, char **argv)
{
cufftHandle plan;
cufftComplex *data;
cufftComplex *digits;
cufftComplex *h_data;

cudaMallocHost((void**)&digits, sizeof(cufftComplex)*8);
digits[0].x = 12.5f; digits[0].y = 0.0f;
digits[1].x = 66.23f; digits[1].y = 0.0f;
digits[2].x = 35.1f; digits[2].y = 0.0f;
digits[3].x = 16.7f; digits[3].y = 0.0f;
digits[4].x = 14.83f; digits[4].y = 0.0f;
digits[5].x = 55.1f; digits[5].y = 0.0f;
digits[6].x = 11.7f; digits[6].y = 0.0f;
digits[7].x = 18.83f; digits[7].y = 0.0f;

cudaMalloc((void**)&data, sizeof(cufftComplex)*8);

cudaMemcpy(data, digits, sizeof(cufftComplex)*8, cudaMemcpyHostToDevice);

if (cufftPlan1d(&plan, 8, CUFFT_C2C, 1) != CUFFT_SUCCESS) {
    fprintf(stderr, "Cuda: cufftPlan1d CUFFT_C2C failed\n");
    return 1;
}

if (cufftExecC2C(plan, data, data, CUFFT_FORWARD) != CUFFT_SUCCESS) {
    fprintf(stderr, "Cuda: cufftExecC2C CUFFT_FORWARD failed\n");
    return 1;
}

if (cudaMalloc((void**)&h_data, sizeof(cufftComplex)*8) != cudaSuccess) {
    fprintf(stderr, "Cuda: cudaMalloc((void**)&h_data failed\n");
    return 1;
}

cudaMemcpy(h_data, data, sizeof(cufftComplex)*8, cudaMemcpyDeviceToHost);


printf("\nOriginal:\n");
for(int i = 0; i < 8; ++i){
    printf("\nRe:%2.5f   Im:%2.5f", digits[i].x, digits[i].y);
} 

printf("\n\n1D-FFT:\n");
for(int i = 0; i < 8; ++i){
    printf("\nRe:%2.5f   Im:%2.5f", h_data[i].x, h_data[i].y);
} 

cudaFree(digits);
cudaFree(data);
cudaFree(h_data);
cufftDestroy(plan);
}
4

3 に答える 3

1

それ以外の:

if (cudaMalloc((void**)&h_data, sizeof(cufftComplex)*8) != cudaSuccess) {
    fprintf(stderr, "Cuda: cudaMalloc((void**)&h_data failed\n");
    return 1;
}

試す:

if (cudaMallocHost((void**)&h_data, sizeof(cufftComplex)*8) != cudaSuccess) {
    fprintf(stderr, "Cuda: cudaMalloc((void**)&h_data failed\n");
    return 1;
}


バイトをCPUにコピーして戻すためです。


cudaMallocHostドキュメントには、 vsのmalloc使用法に関するヒントが記載されています。

cudaError_t cudaMallocHost(void ** ptr、size_t size)

ページロックされ、デバイスにアクセス可能なホストメモリのサイズバイトを割り当てます。ドライバは、この関数で割り当てられた仮想メモリ範囲を追跡し、cudaMemcpy *()などの関数への呼び出しを自動的に高速化します。メモリはデバイスから直接アクセスできるため、malloc()などの関数で取得されるページング可能なメモリよりもはるかに高い帯域幅で読み取りまたは書き込みを行うことができます。cudaMallocHost()を使用して過剰な量のメモリを割り当てると、システムがページングに使用できるメモリの量が減少するため、システムのパフォーマンスが低下する可能性があります。結果として、この関数は、ホストとデバイス間のデータ交換のためにステージング領域を割り当てるために慎重に使用するのが最適です。

于 2012-05-17T04:46:10.283 に答える
1

基本的な問題は、ホストとデバイスのメモリポインタの不適切な混合です。(cudaMallocを使用して)デバイスメモリ割り当てのアドレスをに割り当てましたh_dataが、ホストメモリ内のアドレスへのポインタとして使用しようとしています。それは機能せず、あなたが見ているホストセグメンテーション違反を引き起こしています。例は次のようになります。

#include <cstdlib>
#include <cuda_runtime.h>
#include <cufft.h>

int main(int argc, char **argv)
{
    cufftHandle plan;
    cufftComplex *data, *digits, *h_data;

    digits = (cufftComplex *)malloc(sizeof(cufftComplex)*8);
    digits[0].x = 12.5f; digits[0].y = 0.0f;
    digits[1].x = 66.23f; digits[1].y = 0.0f;
    digits[2].x = 35.1f; digits[2].y = 0.0f;
    digits[3].x = 16.7f; digits[3].y = 0.0f;
    digits[4].x = 14.83f; digits[4].y = 0.0f;
    digits[5].x = 55.1f; digits[5].y = 0.0f;
    digits[6].x = 11.7f; digits[6].y = 0.0f;
    digits[7].x = 18.83f; digits[7].y = 0.0f;

    cudaMalloc((void**)&data, sizeof(cufftComplex)*8);
    cudaMemcpy(data, digits, sizeof(cufftComplex)*8, cudaMemcpyHostToDevice);

    if (cufftPlan1d(&plan, 8, CUFFT_C2C, 1) != CUFFT_SUCCESS) {
        fprintf(stderr, "Cuda: cufftPlan1d CUFFT_C2C failed\n");
        return 1;
    }

    if (cufftExecC2C(plan, data, data, CUFFT_FORWARD) != CUFFT_SUCCESS) {
        fprintf(stderr, "Cuda: cufftExecC2C CUFFT_FORWARD failed\n");
        return 1;
    }

    h_data = (cufftComplex *)malloc(sizeof(cufftComplex)*8);
    cudaMemcpy(h_data, data, sizeof(cufftComplex)*8, cudaMemcpyDeviceToHost);

    printf("\nOriginal:\n");
    for(int i = 0; i < 8; ++i){
        printf("\nRe:%2.5f   Im:%2.5f", digits[i].x, digits[i].y);
    } 

    printf("\n\n1D-FFT:\n");
    for(int i = 0; i < 8; ++i){
        printf("\nRe:%2.5f   Im:%2.5f", h_data[i].x, h_data[i].y);
    } 

    free(digits);
    free(h_data);
    cudaFree(data);
    cufftDestroy(plan);
}

後者のAPIの機能とその使用理由を十分に理解していない限り、ホスト側のメモリを割り当てるにmallocは、プレーンまたはC++演算子を使用する必要があることに注意してください。newcudaMallocHost

于 2012-05-17T05:44:29.287 に答える
0

Linuxを使用している場合は、メモリチェックをオンにして、CUDAデバッガーでアプリを実行してみてください。

nvcc –g –G myapp.cu –o myapp
cuda-gdb myapp
(cuda-gdb) set cuda memcheck on 
(cuda-gdb) run

Windowsを使用している場合はNsight | Enable CUDA Memory Checker、組み込みのCUDAデバッガーからコードを選択して実行します。Nsight | Start CUDA Debugging

また、アプリにコードを追加して、各CUDA呼び出しからの戻り値を確認します。

CUDA Memcheckerの詳細については、以下を参照してください。

http://developer.nvidia.com/nvidia-gpu-computing-documentation#CUDA-MemcheckUserManual

于 2012-05-17T04:13:45.980 に答える