0

このコードを以下に書きました。

 unsigned int* addrArray = (unsigned int*)malloc(sizeof(unsigned int)*DATASETROWS);
 thrust::exclusive_scan(binaryDataSet,binaryDataSet+(sizeof(unsigned int)*DATASETROWS),addrArray);
 free(addrArray);

binaryDataSet はunsigned int*型であり、メモリのこの部分でデータを割り当て、処理し、解放することに問題はありません。しかしaddrArray、問題を引き起こします。プログラムを実行した後、次のエラーが発生します。

*** glibc detected *** ./prog: free(): invalid next size (normal): 0x000000000180be10 ***そしてメモリーマップ。

このコードを代わりに使用すると、このエラーは生成されcudaFree(addrArray)ませんが、後でセグメンテーション違反または glibc malloc メモリ破損の問題が発生します。たとえば、次のように実行します。

unsigned int* addrArray = (unsigned int*)malloc(sizeof(unsigned int)*DATASETROWS);
thrust::exclusive_scan(binaryDataSet,binaryDataSet+(sizeof(unsigned int)*DATASETROWS),addrArray);
const unsigned int compactArraySize = addrArray[DATASETROWS-1] - 1;
printf("%u\n",compactArraySize)
float* compactMinorClass = (float*)malloc(sizeof(float)*DATASETCOLS*compactArraySize);

ポインターでメモリを malloc しようとすると、セグメンテーション違反が発生しcompactMinorClassます (printf正しい出力が得られるため、prefixsum が正しく計算され、出力が addrArray に保存されます)。このプログラムをビルドするには、g++ と nvcc のフラグを次のように設定します。

GXXFLAGS:= -O3 -Wall -Wextra -m64 -std=c++0x

NVCCFLAGS:= -Xcompiler -Wall -Xcompiler -Wextra -m64 -arch=sm_11

(私は GeForce310M を持っているので、sm_11 を設定する必要があります) それで、私の質問は、なぜこの推力関数を実行するとエラーが発生するのか、なぜホストに割り当てられたメモリを解放できないのかということfree()です。

4

1 に答える 1

3

これは正しくありません:

thrust::exclusive_scan(binaryDataSet,binaryDataSet+(sizeof(unsigned int)*DATASETROWS),addrArray);

代わりにこれを試してください:

thrust::exclusive_scan(binaryDataSet,binaryDataSet+(DATASETROWS),addrArray);

ここでの意図は、バイト演算ではなくポインター演算を行うことです。2番目のコードサンプルでも同様です。

また、次のように指定することをお勧めします。

-std=c++0x

しかし、それがあなたの問題の原因であるかどうかはわかりません。

cudaFree通常のホスト ポインターに対しては絶対に実行しないでください。

于 2013-08-12T22:47:54.683 に答える