質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

並列処理

複数の計算が同時に実行される手法

パフォーマンス

コード効率の向上や計算に関する質問には、このタグを使ってください。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Q&A

解決済

2回答

2452閲覧

CUDAによる再帰関数の高速化は可能なのか

Yhaya

総合スコア439

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

並列処理

複数の計算が同時に実行される手法

パフォーマンス

コード効率の向上や計算に関する質問には、このタグを使ってください。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

0グッド

0クリップ

投稿2021/12/04 11:51

タイトルのとおりなのですが、再帰関数をCUDAを使って高速化するというのは可能なのでしょうか?
例えば、配列の各要素に対してある操作をするというのはCUDAを使うことで並列に処理できて高速化が実現されるというのはよくみます。再帰関数の場合には、処理をどう各スレッドに分ければ良いのかわかりませんでした。

試しにフィボナッチ数列のn番目の数字を求めるコードを書いてみました。

cuda

1#include <stdio.h> 2 3__device__ void fib_cuda(int n, int *out) { 4 if (n < 3) { 5 *out = 1; 6 } else { 7 int *p, *pp; 8 p = (int*)malloc(sizeof(int)); 9 pp = (int*)malloc(sizeof(int)); 10 11 fib_cuda(n - 1, p); 12 fib_cuda(n - 2, pp); 13 14 *out = *p + *pp; 15 free(p); 16 free(pp); 17 } 18} 19 20__global__ void fib(int n, int *out) { 21 fib_cuda(n, out); 22} 23 24int main() { 25 int *out; 26 int *d_out; 27 out = (int*)malloc(sizeof(int)); 28 29 cudaMalloc((void**)&d_out, sizeof(int)); 30 cudaMemcpy(d_out, out, sizeof(int), cudaMemcpyHostToDevice); 31 32 fib<<<1, 1>>>(20, d_out); 33 cudaMemcpy(out, d_out, sizeof(int), cudaMemcpyDeviceToHost); 34 printf("%d\n", *out); 35 36 cudaFree(d_out); 37 free(out); 38} 39

このコードは動きはするのですが、単にGPU上でCPUと同じ処理をしただけでGPUの恩恵は皆無です。もし再帰関数の高速化も可能ならば上のコードはどう書かれるべきなのでしょうか?

抽象的な質問で申し訳ないのですがよろしくおねがいします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/12/15 02:28

関係あるかどうかわかりませんが 「フィボナッチ数列 gpu」でググると,検索結果の先頭らへんに,文献: ”CUDA を用いたメッセージ送信型並行計算 Actor モデルの実装”, 高柳, 脇田, IPSJ SIG Technial Report Vol.2012-HPC-135 No.37, 2012/8/3 なるPDFがヒットしました. (私は内容を読んではいませんが)実験の例題としてフィボナッチ数列を扱っているようです. 何かしら並列性のある演算を実装している話かもしれません. (図9を見るに「CPUの方が早いけどね」という話になっているようにも見えますが)
guest

回答2

0

ベストアンサー

cudaは、nVIDIAのGPUを使ってSIMD命令(Single Instruction Multiple Data命令)による機械命令レベルのもっとも細かい並列化を行うためのライブラリです。
つまり、16個なり64個なりのデータを対象にして、ひとつの加算なり乗算なりの命令を出すことで同時に6個なり64個なりの計算を実行することによって高速化を行うためのものです。

一般的には再帰関数はSIMD命令に変換することはできませんが、tail recursionと呼ばれる再帰関数については自動最適化コンパイラがループに変換してSIMD命令を出力できる場合があります。
インテルチップやARMチップに内蔵されているSIMD命令についてはこれを行っているコンパイラは存在するはずです。
しかし、cudaのように決め打ちでライブラリを呼び出すような方式ですと自動最適化コンパイラが介在する余地がありませんので、現在はできませんし、将来的にも難しいと思います。

また、例に挙げられているようなフィボナッチ数列タイプの再帰関数では手動でもループに変換することが困難ですので、将来的にも無理でしょう。

投稿2021/12/04 13:18

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yhaya

2021/12/04 14:06

なるほど、詳しい説明をしていただきありがとうございます。理解できました
guest

0

再帰関数をCUDAを使って高速化するというのは可能なのでしょうか?

再帰関数のままでは並列実行自体ができません。再帰を使わず、並列性を活かせるアルゴリズムを選択する必要があります。

投稿2021/12/04 12:40

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/12/04 12:44 編集

> 試しにフィボナッチ数列のn番目の数字を求めるコードを書いてみました。 行列の累乗を使うことでO(log n)とするアルゴリズムがあります(とはいえ、それはCUDA特有の高速化ではありませんし、2×2行列の操作なので並列化の恩恵もそう大きくありません)。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問