問題タブ [loop-unrolling]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - gcc4 がこのループを展開しないのはなぜですか?
gcc 4.4.6
ドキュメントには次のように記載されています。
私はこのコードをコンパイルしています:
...一度はfunroll-all-loops
最適化あり、一度はなし:
次にdiff
、それぞれのアセンブリ コード (を使用して作成) を比較し-S -fverbose-asm
ます。
生成されるコードは同じです。
ループをdo while
;に変更してみました。ループ カウンターの調整 (最大 100)。ループ本体内のステートメントを変更します。
何が欠けている可能性がありますか?このループが展開されないのはなぜですか?
アップデート
Nikos C--param max-unroll-times=N
は、N を上限としてループ登録パラメータを上げることを提案しました。これは賢明な提案でしたが、動作は変わりませんでした。また、ループの反復回数を 10 回に減らしました。また、実際に何かを「実行」するようにコードを更新しましたが、変更はありません。
compiler-construction - コンパイラを使用してAMDOpenCLカーネルのループを展開する方法はありますか?
OpenCLforAMDとNvidiaGPUのパフォーマンスの違いを評価しようとしています。行列とベクトルの乗算を実行するカーネルがあります。現在、カーネルを2つの異なるシステムで実行しています。1つはUbuntu12.04とCUDA4.0(OpenCLライブラリとヘッダーを含む)を搭載したNVidia GT525mを搭載したラップトップで、もう1つはUbuntuを搭載したAMDRadeonHD7970を搭載したデスクトップです。 12.04および最新のCatalystドライバー。
カーネルには#pragma unroll
、Nvidia OpenCL実装の大幅な高速化(〜6x)を実現する2つのステートメントがあります。ただし、AMDOpenCLバージョンではスピードアップは発生しません。AMD APPカーネルアナライザーでカーネルを見ると、トリップカウントが不明なため、展開が使用されていないというエラーが表示されます。だから私の質問は、#pragma unroll
AMD OpenCLで動作するのか、それとも代替手段があるのか(おそらく私が知らないコンパイラフラグ)です。以下にカーネルを含めました
この同じカーネルは両方の実装で正しい結果を生成しますが、#pragma unrollコマンドはAMDに対して何もしません(コメントアウトしてチェックアウト)。
javascript - JavaScript ループの展開
次のような立方体の 3D 配列「クラス」があります。
アクセスのパフォーマンスに影響を与えずに、多次元に一般化したいと考えています。これが私の簡単なアプローチです:
関数を「展開」makeIndex
して、ループが宣言時に 1 回評価され、呼び出し時には評価されないようにする方法はありますか? 実行時に生成されたコードを使用することのオーバーヘッドは、ループしないことのメリットを相殺するでしょうかeval
?new Function()
size
とはどちらN
も本質的に定数であるため、乗算と反復の繰り返しは 1 回しか実行できないように感じます。
vectorization - 平坦化された fortran 行列のループ
次のようなコードが少しあります。
つまり、次元 54 の配列 premultz があります。次元 501 の配列 sinphi があります。sinphi の最初の値に premultz のすべてのエントリを掛けて、arg1 の最初の 54 エントリに格納し、次にsinphi の 2 番目の値は、premultz のすべてのエントリを掛けて、arg1 の second54 エントリに格納します。
これらは平坦化された行列です。このプロジェクトの主な目標の 1 つは非常に高速なコードであるため、速度のためにそれらを平坦化しました。
私の質問はこれです: Fortran90 でこの種の計算をコーディングするより効率的な方法はありますか? Fortran には、私が十分に認識していない気の利いた配列操作がたくさんあることを知っています。
前もって感謝します。
c++ - (c++) このループを最適化する方法はありますか? クラス内で関数ポインタを使用することはできません
関数の最適化を試みていfun_a1()
ます。変数j
は のスコープでは変更されませんfun_a1()
。したがって、「i」反復ごとに j==1 または 2 または 3 をチェックすることは、明らかに CPU サイクルの無駄です。しかし、条件評価をループの外に出そうとすると、条件ごとに冗長なループを書かなければなりません。C では、関数ポインターを使用してこれを簡単に解決できます。ただし、C++ は非静的関数へのポインターを許可しません。不思議な「メンバーへのポインター」を説明するリンクがいくつか見つかりました。(例 1、例 2 ) しかし、オブジェクト自体の内部から、たとえば fun_a() の内部からどのように使用すればよいかはまだ明確ではありません。または、他の方法で最適化できますか?
cuda - cuda - ループ展開の問題
のカーネルがあり、#pragma unroll 80
NVIDIA GT 285、コンピューティング機能 1.3、グリッド アーキテクチャで実行してdim3 thread_block( 16, 16 )
いdim3 grid( 40 , 30 )
ます。問題なく動作します。
NVIDIA GT 580、計算能力 2.0、および上記のグリッド アーキテクチャで実行してみたところ、問題なく動作しました。
GT 580 のグリッド アーキテクチャを
dim3 thread_block( 32 , 32 )
そしてdim3 grid( 20 , 15 )
、上記と同じ数のスレッドを生成するため、間違った結果が得られます。
GT 580でそれを削除#pragma unroll 80
または交換すると、正常に動作します。#pragma unroll 1
そうしないと、カーネルがクラッシュします。
なぜこれが起こるのか誰にも分かりますか?前もって感謝します
編集:両方のデバイスでカーネルエラーをチェックしたところ、「無効な引数」が表示されました。このエラーの原因を検索したところ、グリッドとブロックのサイズが制限を超えたときに発生することがわかりました。しかし、私はブロックごとに 16x16=256 スレッド、合計 40x30=1200 ブロックを使用しているため、これは当てはまりません。私の知る限り、これらの値は計算能力 1.3 の GPU グリッドの境界にあります。これが私が抱えているループ展開の問題と関係があるかどうか知りたいです。
c - 従属ループを使用したループ展開
特定のプロシージャの後続の依存ループでループ展開を実行する必要がある大規模なアプリケーションに取り組んでいます。より大きなバージョンを複製するために、以下に小さなサンプルコードを書きました。
元のコードを考えてみましょう:
ここで、ループi
を 2 倍に展開します。
i
ここで、ループをj
2 倍に展開したいと考えていますが、 loop は loopj
に依存しi
ているため、どのように記述すればよいか少しわかりません。コードを書き直して、両方i
とj
2 倍に展開するにはどうすればよいですか。また、展開係数を大きくすると、コードはますますぎこちなくなります。コードが醜くなりすぎずに、手動で展開する賢い方法はありますか?
この特定のケースでは、コンパイラ フラグ (例:-funroll-loops) を使用できません。手動ループ展開でアプローチしたい。
お時間をいただきありがとうございます。