2017-02-18 9 views
-1

私はCUDAカーネルを作成しています。整数除算と定数を使って私の頭を傷つけてしまいます。
私は以下の何が起こるかを説明しましょう:定数の整数分け

#define X 8 
#define Y 4 
#define K X/Y 
...code.... 
int var = 8; 
...code.... 
printf("K = %d, var = %d, var/K = %d\n", K, var, var/K); 

私はどこかのループで終了条件としてVAR/Kを使用しています、と私はそのVARを疑うだろう/ Kは4の値を与えるだろうが、それが与えます代わりに1の値を指定してカーネルを破壊します。私はの#defineからint型のグローバル定数にKを変更すると

K = 2, var = 8, var/K = 1 

:ここではprint文の出力がある

__device__ const int K=X/Y; 

問題が消える、除算結果は、4を与えます私のカーネルは正しく機能します。私はKをintにキャストしようとしましたが(これは必要ではありません)、それは何も変わりません。
定数の分割にいくつかの制限があるのか​​、どこかに基本的な誤解があるのだろうかと思います。

+2

プリプロセッサはテキストの置き換えに過ぎないので、あなたの定義は '8/8/var/K'だがなぜそれが '1'になるのだろう? – deamentiaemundi

+2

これはCUDAとはまったく関係がなく、プリプロセッサ独特のものです... – CygnusX1

+0

divisionnの代わりに乗算 –

答えて

3

ここでの基本的な問題は、CUDAとは関係がありません。それは普通のC/C++コンパイラで明らかになります。コメントで示されているように

、これら2つの異なる方法で「定数」を作成する:あなたが発見したとして

#define K X/Y 

const int K=X/Y; 

すると、すべての場合に同じことを得られません。最初の方法では、CまたはC++ プリプロセッサを使用してコードを実行し、X/Yのリテラル(テキスト)置換をKとする任意の場所に置き換えます。だから、あなたがこれを行うとき:

int var = 8; 
printf("K = %d, var = %d, var/K = %d\n", K, var, var/K); 

言語処理が始まる前var/Kは文字通り、var/X/Yに置き換えます表現。そして、CとC++は左から右へそのような式を評価するので、期待した結果が得られません。

第2の方法論はもちろん、実際の変数を作成し、期待どおりに動作します。ここでも、これはCUDA特有のものではありません。式を伴う

プリプロセッサマクロ(すなわち#define)を使用している場合、それは、一般的な勧告を風変わりな行動のすべての種類を削除しないかもしれないが、そうのように、常にこのようなマクロの周りに括弧を使用することです:

#define K (X/Y) 

この一般的には、マクロ内のテキスト式を、意図と一貫性のある方法で言語プロセッサーによって評価されるようにします。特に、マクロ自体の式が評価される前に、マクロのいくつかの部分が隣接する操作に関与しているような、望ましくない副作用を防ぎます。もちろん、グローバル変数constを定義するだけで、既に発見したように機能し、より良い選択となる場合もあります。

コメントでもう一度言及しておきますが、ここで示したように、私はvar/Kがあなたが与えた場合0ではないと評価されると思います。しかし、あなたは完全なコードを表示していないので、ここには何か他のものがあるかもしれません。そしてその意見の違いにかかわらず、あなたが示したマクロの使用はあなたの期待される結果を8/2 = 4に与えません。あなたが主張しているように0でなければならないかどうかにかかわらず、あなたの期待する結果は4になりません。

関連する問題