アーカイブ
実はAdvanced/W-Zero3[es]が欲しいかもしれない
とりあえずスマートフォンが欲しいのですよ。
で、一応Softbankからも出てるし、来月にはX01Tが出るわけなんだが。
どうもサイトを見ると料金プランがわからん。パケットし放題に「月額1,029円~4,410円で、国内はメールもウェブもし放題!(PCサイトブラウザ除く)」とか書いてあるし。
っつーわけで、圏外率最強クラスの3Gを980円プランに変更して(変更しても家族間通話とかは安いはずだし)、アドエス買っちゃうのが一番幸せになれるかなあとか考えているわけだ。
どうせプリンタとかレコーダとかいじるために週末に秋葉ヨドバシあたりへ行ってこようと思っているので、ついでに料金のこととかも聞いてくるか。
ほとんど通話をしないから料金なんて対してかからないぜふふーんとか思っていると、たまにサポセンだのなんだのにかけた後に料金表示を見て3桁の数字が出てくるのが納得いかないんだよなあ。
CUDAでN-QUEENやってみた
主に、CUDAでプログラムを組むとこんな感じだよーってのをチェックするため。こんなもの高速化しても論文になりませ……ならないと思います。多分。
とりあえず問題サイズと同じだけの並列化*もやってちょうど200行くらい。少なくともシェーダを叩くよりはやりやすいと思う。メモリの扱いだけ気をつければ、単純なCで書ける。まあそのメモリの扱いがめんどいんだけどさ。
(* : N=8の時は8並列。要するに、IDがnの人は1列目のクイーンをn行目に置くと仮定してネ、っていう並列化。)
問題サイズを12より大きくするとこけるのはなんだろう。とりあえずでっちあげただけなのでちゃんと調査してません。もしかしたらスレッド(CUDAの実行モデルで言うところの一番小さい単位。スレッドを束にしたブロックとかいう単位もある。まぁいわゆるスレッド並列化のスレッドと考えていいよ。)の何らかの制限を突破してるかもね。メモリ量とか時間とか。シェーダみたいにループの回数制限とかあったっけかなぁ?
ちなみに実行時間を測定したところ、CPUの非並列非再帰版より明らかに遅かった。更に細かく並列化して高速化する余地というかアイディアはありまくりなので、この後もうちょっと頑張って高速化するかもね。しないかもね。
一応フルソース載せておきます。参考になるかは知らない。とっとと帰ってゼミ資料でも捏造して寝ます。CUDAたんと戯れていたら東急ストアの特売日逃したよチクショウ!
-
</p>
-
<p>#include <stdlib.h></p>
-
<p>#include <stdio.h></p>
-
<p>#include <string.h></p>
-
<p>#include <math.h></p>
-
<p>#include <unistd.h></p>
-
-
<p>#include <cutil.h></p>
-
-
<p>#define N 12</p>
-
-
<p>__global__ void test(</p>
-
<p> int size,</p>
-
<p> int* numAnswers,</p>
-
<p> int* E,</p>
-
<p> int* SE,</p>
-
<p> int* NW,</p>
-
<p> int* answer,</p>
-
<p> int* etc</p>
-
<p>)</p>
-
<p>{</p>
-
<p> int id = threadIdx.x;</p>
-
<p> if(id>size){</p>
-
<p> if(id<size*2){</p>
-
<p> etc[id] = -1;</p>
-
<p> }</p>
-
<p> return;</p>
-
<p> }</p>
-
<p> etc[id] = 1;</p>
-
<p> if(threadIdx.y>0){</p>
-
<p> return;</p>
-
<p> }</p>
-
<p> int offset1 = id*size;</p>
-
<p> int offset2 = id*(size*2-1);</p>
-
<p> int x, y;</p>
-
<p> x=0;</p>
-
<p> y=id;</p>
-
<p> answer[offset1+x] = y;</p>
-
<p> E[offset1+y] = 1;</p>
-
<p> SE[offset2+(size-1)-x+y] = 1;</p>
-
<p> NW[offset2+x+y] = 1;</p>
-
<p> x++;</p>
-
<p> y=0;</p>
-
-
<p> while(1){</p>
-
<p> if(x==size){</p>
-
<p> // all OK</p>
-
<p> //printAnswer(d);</p>
-
<p> numAnswers[id]++;</p>
-
<p> x--;</p>
-
<p> y = answer[offset1+x];</p>
-
<p> //removeQueen(d,x,y);</p>
-
<p> E[offset1+y] = 0;</p>
-
<p> SE[offset2+(size-1)-x+y] = 0;</p>
-
<p> NW[offset2+x+y] = 0;</p>
-
<p> y++;</p>
-
<p> }else if(y==size){</p>
-
<p> x--;</p>
-
<p> if(x<1){</p>
-
<p> break;</p>
-
<p> }</p>
-
<p> y = answer[offset1+x];</p>
-
<p> //removeQueen(d,x,y);</p>
-
<p> E[offset1+y] = 0;</p>
-
<p> SE[offset2+(size-1)-x+y] = 0;</p>
-
<p> NW[offset2+x+y] = 0;</p>
-
<p> y++;</p>
-
<p> }else{</p>
-
-
<p> int test=0;</p>
-
<p> if(E[offset1+y] || SE[offset2+(size-1)-x+y] || NW[offset2+x+y]){</p>
-
<p> test=0;</p>
-
<p> }else{</p>
-
<p> answer[offset1+x] = y;</p>
-
<p> E[offset1+y] = 1;</p>
-
<p> SE[offset2+(size-1)-x+y] = 1;</p>
-
<p> NW[offset2+x+y] = 1;</p>
-
<p> test=1;</p>
-
<p> }</p>
-
-
<p> if(test==1){</p>
-
<p> x++;</p>
-
<p> y=0;</p>
-
<p> }else{</p>
-
<p> y++;</p>
-
<p> }</p>
-
<p> }</p>
-
<p> }</p>
-
<p> //etc[id] = offset;</p>
-
<p>}</p>
-
-
<p>void</p>
-
<p>runTest(int argc, char** argv)</p>
-
<p>{</p>
-
<p> CUT_DEVICE_INIT();</p>
-
-
<p> printf("%d Byte\n", (1+N+N*N+(N*(N*2-1))+(N*(N*2-1))+N*N)*4);</p>
-
<p> </p>
-
<p> // CPU側のデータを準備</p>
-
<p> int size;</p>
-
<p> int numAnswers[N];</p>
-
<p> int E[N*N];</p>
-
<p> int SE[N*(N*2-1)];</p>
-
<p> int NW[N*(N*2-1)];</p>
-
<p> int answer[N*N];</p>
-
<p> int etc[N*2];</p>
-
-
<p> int i;</p>
-
<p> size = N;</p>
-
<p> for(i=0; i<N; i++){</p>
-
<p> numAnswers[i] = 0;</p>
-
<p> }</p>
-
<p> for(i=0; i<N*2; i++){</p>
-
<p> etc[i] = 0;</p>
-
<p> }</p>
-
<p> for(i=0; i<N*N; i++){</p>
-
<p> E[i] = 0;</p>
-
<p> answer[i] = 0;</p>
-
<p> }</p>
-
<p> for(i=0; i<N*(N*2-1); i++){</p>
-
<p> SE[i] = 0;</p>
-
<p> NW[i] = 0;</p>
-
<p> }</p>
-
-
<p> // GPU側のメモリを準備</p>
-
<p> int* d_numAnswers;</p>
-
<p> int* d_E;</p>
-
<p> int* d_SE;</p>
-
<p> int* d_NW;</p>
-
<p> int* d_answer;</p>
-
<p> int* d_etc;</p>
-
-
<p> CUDA_SAFE_CALL(cudaMalloc(<a href="#hs_11b98399da989688ba0f94d4ee753bfd_footnote_1" id="hs_11b98399da989688ba0f94d4ee753bfd_footnotelink_1" title="void**)&d_numAnswers, sizeof(int)*N">*1</a>);</p>
-
<p> CUDA_SAFE_CALL(cudaMalloc(<a href="#hs_11b98399da989688ba0f94d4ee753bfd_footnote_2" id="hs_11b98399da989688ba0f94d4ee753bfd_footnotelink_2" title="void**)&d_E, sizeof(int)*N*N">*2</a>);</p>
-
<p> CUDA_SAFE_CALL(cudaMalloc(<a href="#hs_11b98399da989688ba0f94d4ee753bfd_footnote_3" id="hs_11b98399da989688ba0f94d4ee753bfd_footnotelink_3" title="void**)&d_SE, sizeof(int)*(N*2-1)*N">*3</a>);</p>
-
<p> CUDA_SAFE_CALL(cudaMalloc(<a href="#hs_11b98399da989688ba0f94d4ee753bfd_footnote_4" id="hs_11b98399da989688ba0f94d4ee753bfd_footnotelink_4" title="void**)&d_NW, sizeof(int)*(N*2-1)*N">*4</a>);</p>
-
<p> CUDA_SAFE_CALL(cudaMalloc(<a href="#hs_11b98399da989688ba0f94d4ee753bfd_footnote_5" id="hs_11b98399da989688ba0f94d4ee753bfd_footnotelink_5" title="void**)&d_answer, sizeof(int)*N*N">*5</a>);</p>
-
<p> CUDA_SAFE_CALL(cudaMalloc(<a href="#hs_11b98399da989688ba0f94d4ee753bfd_footnote_6" id="hs_11b98399da989688ba0f94d4ee753bfd_footnotelink_6" title="void**)&d_etc, sizeof(int)*N*2">*6</a>);</p>
-
-
<p> CUDA_SAFE_CALL(cudaMemcpy(d_numAnswers, &numAnswers, sizeof(int)*N, cudaMemcpyHostToDevice) );</p>
-
<p> CUDA_SAFE_CALL(cudaMemcpy(d_E, E, sizeof(int)*N*N, cudaMemcpyHostToDevice) );</p>
-
<p> CUDA_SAFE_CALL(cudaMemcpy(d_SE, SE, sizeof(int)*(N*2-1)*N, cudaMemcpyHostToDevice) );</p>
-
<p> CUDA_SAFE_CALL(cudaMemcpy(d_NW, NW, sizeof(int)*(N*2-1)*N, cudaMemcpyHostToDevice) );</p>
-
<p> CUDA_SAFE_CALL(cudaMemcpy(d_answer, &answer, sizeof(int)*N*N, cudaMemcpyHostToDevice) );</p>
-
<p> CUDA_SAFE_CALL(cudaMemcpy(d_etc, &etc, sizeof(int)*N*2, cudaMemcpyHostToDevice) );</p>
-
<p> </p>
-
<p> // 実行のためのパラメタを準備</p>
-
<p> dim3 threads(N, 1, 1);</p>
-
<p> dim3 grid(1,1,1);</p>
-
-
<p> // 実行</p>
-
<p> unsigned int hTimer;</p>
-
<p> CUT_SAFE_CALL( cutCreateTimer(&hTimer) );</p>
-
<p> CUT_SAFE_CALL( cutResetTimer(hTimer) );</p>
-
<p> CUT_SAFE_CALL( cutStartTimer(hTimer) );</p>
-
<p> test<<<grid, threads>>>(size, d_numAnswers, d_E, d_SE, d_NW, d_answer, d_etc);</p>
-
<p> CUDA_SAFE_CALL( cudaThreadSynchronize() );</p>
-
<p> CUT_SAFE_CALL( cutStopTimer(hTimer) );</p>
-
<p> double gpuTime = cutGetTimerValue(hTimer);</p>
-
<p> printf("Time: %f ms\n", gpuTime);</p>
-
-
<p> // GPUの処理に問題が起きていないかの確認 </p>
-
<p> CUT_CHECK_ERROR("Kernel execution failed");</p>
-
-
<p> // 演算結果の取得</p>
-
<p> CUDA_SAFE_CALL(cudaMemcpy(&numAnswers, d_numAnswers, sizeof(int)*N, cudaMemcpyDeviceToHost) );</p>
-
<p> CUDA_SAFE_CALL(cudaMemcpy(&etc, d_etc, sizeof(int)*N, cudaMemcpyDeviceToHost) );</p>
-
-
<p> // 演算結果の確認</p>
-
<p> int nAll=0;</p>
-
<p> for(i=0; i<N*2; i++){</p>
-
<p> printf(" %d", etc[i]);</p>
-
<p> }</p>
-
<p> printf("\n");</p>
-
<p> for(i=0; i<N; i++){</p>
-
<p> nAll += numAnswers[i];</p>
-
<p> printf(" %d\n", numAnswers[i]);</p>
-
<p> }</p>
-
<p> printf("sum %d\n", nAll);</p>
-
-
<p> // クリーンアップ</p>
-
<p> //free();</p>
-
<p> CUDA_SAFE_CALL(cudaFree(d_numAnswers));</p>
-
<p> CUDA_SAFE_CALL(cudaFree(d_E));</p>
-
<p> CUDA_SAFE_CALL(cudaFree(d_SE));</p>
-
<p> CUDA_SAFE_CALL(cudaFree(d_NW));</p>
-
<p> CUDA_SAFE_CALL(cudaFree(d_answer));</p>
-
<p> CUDA_SAFE_CALL(cudaFree(d_etc));</p>
-
<p>}</p>
-
<br />
-
-
<p>int</p>
-
<p>main(int argc, char** argv)</p>
-
<p>{</p>
-
<p> runTest(argc, argv);</p>
-
<p> </p>
-
<p> CUT_EXIT(argc, argv);</p>
-
<p>}</p>
-
-
<p>
最近のコメント