ライトコインマイニングの最適化

みなさんこんにちは! ライトコインのマイニングアルゴリズムをどのように最適化したかについてお話しすることにしました。 そして、私は私の物語を日記の形で提示します。



0日目:私は、コミュニティとビットレスがマイニングを数パーセント高速化する方法を共有するトピックに出会いました。 彼は自問しました:なぜ私は彼よりも悪いのですか? 私はコードを分析し始めました。

1日目:構文を覚えています。OpenCLの機能に関する情報を見つけます。

2日目:非常に奇妙なコード行に遭遇しました。



#define Coord(x,y,z) x+y*(x ## SIZE)+z*(y ## SIZE)*(x ## SIZE) #define CO Coord(z,x,y)
      
      







2行目の1行目を組み立てて、



 #define CO z+x*zSIZE+y*xSIZE*zSIZE
      
      







なぜ庭をフェンスで囲む必要があったのか-scrypt_core関数で未使用の変数ySIZEが見つかったことがわかりません。

また、検索機能では、i * 2の複数の使用法を見つけ、rotl(i、1U)に置き換えました。 これによりパフォーマンスは向上しませんでしたが、そのままにしてください。



3日目:現在の知識レベルで何かを最適化する唯一のチャンスは、デフォルト設定ではz + x * zSIZE + y * xSIZE * zSIZEが8704回と見なされるため、「CO」でコンパイラを支援することであることに気付きました。 ほとんどの場合、コンパイラは何らかの方法でこれらの計算を最適化しますが、これは少し助けになることを妨げません:)さらに、zSIZEは8に等しい定数で、xSIZEはプログラム設定から取得した定数です。

彼は「CO」が使用される最初のサイクルを探り始めました:



  for(uint y=0; y<1024/LOOKUP_GAP; ++y) { #pragma unroll for(uint z=0; z<zSIZE; ++z) lookup[CO] = X[z]; //    }
      
      







xはループの実行中に変化しないため、x * zSIZEは定数であることがわかります。 また、ループの反復ごとにyが1ずつ増加することも明らかです。



これを理解すると、x * zSIZEが最初に格納されるCO変数の作成を要求し、ループの各反復でxSIZE * zSIZEが追加されます。



そして、変数zが私たちの邪魔にならないように、ループ内にローカル変数を作成し、内部ループの各繰り返しの後にローカル変数を追加します。



上記の理由に加えて、これによりコンパイラーはこの変数をレジスターにプッシュできるようになる可能性があり、これによりプロセスの速度も向上するはずです。



結果は次のコードです。



  uint CO=rotl(x,3U);// x*zSIZE uint CO_tmp=rotl(xSIZE,3U);//xSIZE*zSIZE for(uint y=0; y<1024/LOOKUP_GAP; ++y, CO+=CO_tmp) { uint CO_reg=CO; #pragma unroll for(uint z=0; z<zSIZE; ++z, ++CO_reg) lookup[CO_reg] = X[z]; //    }
      
      







4日目:次の「CO」の使用を分析します。 プリプロセッサでコードが1回だけ使用されるため、コードをスキップします。



  for (uint i=0; i<1024; ++i) { uint4 V[8]; uint j = X[7].x & K[85];//K[85]=0x000003FFU uint y = (j/LOOKUP_GAP); #pragma unroll for(uint z=0; z<zSIZE; ++z) V[z] = lookup[CO]; //    }
      
      







yはかなり複雑なアルゴリズムに従って変化し、この変数の値を予測する可能性は低いことがわかります。

したがって、私ができるのは、x * zSIZEとxSIZE * zSIZEを事前に計算することだけです。



  CO_tmp=rotl(x,3U); CO=rotl(xSIZE,3U); for (uint i=0; i<1024; ++i) { uint4 V[8]; uint j = X[7].x & K[85]; uint y = (j/LOOKUP_GAP); uint CO_reg=CO_tmp+CO*y; for(uint z=0; z<zSIZE; ++z, ++CO_reg) V[z] = lookup[CO_reg]; //    }
      
      







5日目:コンパイルして、構成が3%増加することを確認します。 結果を数回確認した後、コードを人間の形にし、2番目のサイクルのようにプリプロセッサーセクションでコードを最適化し、以前に作成したi * 2のrotl(i、1U)による置換を削除します。



「クリーンな」コードのテストの後、結果は私を驚かせます-速度は私の最適化の開始前よりもずっと遅くなりました。 少し調べてみると、この理由はrotl(i、1U)ではなくi * 2が返されていることがわかりました。

交換自体では何も得られないように思われます。何度かチェックしましたが、最適化とともに速度が向上しました。



仕事の結果をCon Colivasのメールに送信します。



12日目:1週間以内に回答を待つことなく、成果と指示をLightcoin公式フォーラムに投稿します。

数人で動作し、実際に速度が向上しました。 しかし、すぐに問題が発生しました-ドライバー13.4と、以前のバージョンのドライバー(およびOpenCl)でテストを実施しました-速度が約3分の1低下しました。

ドライバー13.1を自分用にインストールしました(問題なく-OpenClバージョンは、AMDおよびOpenCLドライバーがシステムから完全に削除されるまでダウンしませんでした)、私は研究を始めています。



13日目:パフォーマンスの低下は、同じ不思議なi * 2からrotl(i、1U)への置き換えが原因であることがわかりました。 ただし、この置換を削除すると、速度は初期レベルに戻ります。



2つのバージョンの最適化を実行する必要があることを理解しています。13.4と古いバージョンのドライバーです。



13〜40日目:自主的なテスターを収集した後、13.1で最適化が壊れていると報告した人々のうち、私は仕事を始めました。

テスト中に、鉄に依存した最適化が検出され、すぐに拒否します(たとえば、計算されたy * xSIZE * zSIZE値を格納する1024要素の配列を作成します(y = 0..1023の場合)-最適化は機能しましたが、テスターはありません)、およびいくつかの最適化の結果に対する周波数の非線形効果:1000/1300の周波数での私の7850では、13の強度で毎秒340キロヘクセのような異常な結果が発行されましたグラフィックカードが私の場合 t)は、代わりに私の最適化なしで毎秒〜200 kilohesheyのおよび/または他の周波数で。



しかし、私はそのような最適化を拒否しなければなりませんでした(ほとんど、私自身はこのバージョンを保存しました)。



--thread-concurency設定の「マジック値」も見つかりました。この値では、速度が増加し、2 ^ n + 1に等しくなります(例:4097または16385)。他の値の場合、マイニング速度は遅くなります。



私の仮定-2 ^ n + 1の乗算が最速である可能性がありますが、2 ^ nの乗算は左への単純なビットシフトであり、理論的には高速であるため、これは完全に論理的ではありません...



私は次のコードになりました:



  uint CO_tmp=xSIZE<<3U;//xSIZE*zSIZE uint CO_tmp2=x<<3U;//x*zSIZE for(uint y=0; y<1024/LOOKUP_GAP; ++y) { uint CO=y*CO_tmp+CO_tmp2; #pragma unroll for(uint z=0; z<zSIZE; ++z,++CO) lookup[CO] = X[z]; //    } //  for (uint i=0; i<1024; ++i) { uint4 V[8]; uint j = X[7].x & K[85]; uint y = (j/LOOKUP_GAP); uint CO=y*CO_tmp+CO_tmp2; #pragma unroll for(uint z=0; z<zSIZE; ++z) V[z] = lookup[CO+z]; //    }
      
      







同じフォーラムで13.4より古いドライバーのバージョンを公開し、「魔法の価値」--thread-concurencyに言及しました。 そして彼の仕事が完了したことがわかりました。



i * 2がrotl(i、1U)に置き換えられたときに何が起こるか、そして--thread-concurencyパラメーターの「マジック値」の性質を、知識のある人が教えてくれることを願っています。



lightcoinsフォーラムに関する私のトピック: forum.litecoin.net/index.php?topic=4082.0



PSすべての作業は、scrypt.clファイルで実行されました。このファイルは、ライトコインマイニングをサポートするマイナーのキットに含まれています。



All Articles