私はNvidiaのGPUアーキテクチャを理解しようとしていますが、非常に単純に見えるものに少し固執しています。 Pascalの各ストリーミングマルチプロセッサは、64xFP32コアと32xFP64コアで構成されています。そして、ここに私の2つの質問があります:
どちらもハードウェア設計の決定だと思いますが、このトピックについて詳しく知りたいと思います。これに関する情報は大歓迎です!
編集1:
NvidiaがFP32ユニットとFP64ユニットの両方をチップに搭載したのはなぜですか?
できるだけ多く売るために、市場への浸透について考えています。 FP64がないと、科学研究者はFP64を使用する科学的に重要なgpgpuソフトウェアのデモを試すことさえできません(ゲームでさえ倍精度を使用する場合があります)。 FP32がないと、ゲームの物理とシミュレーションが非常に遅くなるか、GPUに原子炉が必要になります。 FP16がなければ、高速ニューラルネットワークはありません。 FP32しかない場合、ニューラルネットワークシミュレーションは半分の速度で機能するか、FP64の合計が機能しません。
誰が知っているか、おそらく将来的には超高速でレイトレーシングを行うFP_raytrace専用コアがあるので、DX12 DX11DX9の面倒なアップグレードやより良いグラフィックスはもうありません。
最終的には、一部のコアをFP64からFP32に、またはアプリケーションの一部の特殊機能コアを変換し、次にすべてを別のアプリケーションのFP64に変換し、さらにすべてを単一のファットコアに変換できるFPGAベースのGPUについてはノーとは言えません。シーケンシャルな作業(シェーダーのコンパイルなど)を行っています。これは、コンピューター上でさまざまなことを行う人々にとって有益です。たとえば、加算よりも多くの乗算が必要な場合があり、FPGAがここで役立ちます。しかし今、お金が話し合い、「今のところ固定機能」と書かれており、FP64とFP32(そして最近はFP16)を組み合わせることで最高の収入が得られます。
(CPUのSIMD命令セットのように)命令ごとに2xFP32操作を実行できるFP64ユニットを配置しないのはなぜですか。
SIMDは、複数のデータに対して常に同じ操作を期待し、スカラーGPGPUカーネルに対してはあまり面白くないことを期待しています。また、FP64から2xFP32を作成するには、純粋なFP64よりも多くのトランジスタ、より多くの熱、より多くの遅延が必要になる可能性があります。
トランジスタが多い=生産障害の可能性が高いため、512 FP64_flexibleGPUよりも1024FP32GPUが生産される可能性が高くなります。
FP32とFP64のすべてのユニットを同時に使用できないのはなぜですか?
混合精度コンピューティングはcudaとopenclで実行できるため、すべてのコアを使用してさらに高速化できますが、まれでコーディングが難しい非メモリボトルネックの状況にのみ適用できます。
編集への回答1:
詳細なソースは次のとおりです http://www.nvidia.com/content/PDF/sc_2010/CUDA_Tutorial/SC10_Accelerating_GPU_Computation_Through_Mixed-Precision_Methods.pdf
簡単に言えば、彼らは付け加えません。異なる精度の計算の間に必要な「余分なサイクル」のために、どういうわけかすべてのコアで%100のスケーリングを許可しない「収穫逓減」があります。それらが混合されていない場合、ブロック間で「追加の反復」が必要になります。これにより、%100のスケーリングもできなくなります。 「FP32」をダウンさせるのではなく「FP64」をスピードアップする方が便利なようです(ただし、FP64コアが多数あると(FP32をアップする場合)有益であるはずです。nbodyカーネル(メモリのボトルネックではありません)のようなものでテストできます) )。 FP64は非常にメモリを消費します(そしてキャッシュライン(およびローカルメモリ))。そのため、Nbody alorithmを提案しました。これは、一部のデータをN(> 64k)回再利用します。私のGPUは1/24FP64パワーを持っているので、私のコンピューターを信用していません。あなたは巨人を持っていますか?試してみる必要があります。おそらく、アドバタイズメントGFLOP値よりも50%多い電力を持っています(ただし、アドバタイズメントTDP値は、その頻度を制限し、溶けてしまう可能性があります)
「卓越したパフォーマンスと精度」と書かれていますが、FP32 + FP32(切り捨てられたFP64)を使用するゲームの物理ソルバーが見つかりませんでした。誰かがこれを行うと、ゲームの「卓越したパフォーマンスとメルトダウン」になるでしょう。 (GPUを爆発させるファーマークよりも悪いかもしれません)
人々はここでフロートの上に整数(整数ドット積)を使用することさえあります: https://devblogs.nvidia.com/parallelforall/mixed-precision-programming-cuda-8/
CUDAの場合、これはどのように達成されますか?カーネルでdoubleとfloatを同時に使用するだけですか?または、何らかのフラグをNVCCに渡す必要がありますか?
同じ関数でfp64 + fp32を使用した反復リファインメントの例:
https://www.sciencesmaths-paris.fr/upload/Contenu/HM2012/07-dongarra_part2.pdf
26〜28ページ。
Openclの部分については、サイクルごとに1dp fma + 1 sp(または1 sf)を発行できるAMDエバーグリーン(hd5000シリーズ)があります。
http://www.microway.com/download/whitepaper/gpgpu_architecture_and_performance_comparison_2010.pdf
明日は、R7-240でnbodyのようなものをテストします。これはfp32の1/24または1/26の累乗です。
編集:その動作。
__kernel void sumGPU(__global float * a,__global float * b)
{
int idx = get_global_id(0);
float a0=a[idx];
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
//a0=convert_float(convert_double(a0)+2.0);
//a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
a0+=2.0f;
b[idx] = a0;
}
コメントの1つだけが無効になっている場合は、13.02ミリ秒と12.85ミリ秒の間で切り替わります。
注:コア自体はfp32ではありません。コアはありません。ハードウェアリソース(fp32、fp64、special_function、registers)をスレッドのカーネル命令にバインドするスケジューラがあります。スレッドも実際のスレッドではありません。したがって、fp32、fp64、fp32、fp64_square_rootの順に使用すると、必要なときに必要なリソースが予約されます。そうでない場合、それらは他の作業項目のオプションです(ただし、1つの作業項目で1〜2個を超えるfp32 ALUを使用することはできません(idk、これを作成しました))
編集(2018/03):はFP_raytrace
(上記のこの回答の2番目の段落)は現実になりますか?
(NVIDIA) https://www.geforce.com/whats-new/articles/nvidia-rtx-real-time-game-ray-tracing
それとも別のマーケティングギミックですか?ハードウェア側がある場合、レイトレーサーの人々はより速く作業できますが、モバゲーマーやレイトレーサーのない物理シミュレーターには役立ちません。いくつかのビデオを編集する場合、なぜこれらのレイトレーサーにもっとお金を払うのですか?たぶん、これらも他のものとしてセグメント化することができますが、おそらくもっとお金がかかります。