2016-06-27 3 views
1

ここではhttp://primates.ae/のCでPRIMATEs暗号のビットスライス実装を実装しました。私はSIMDプログラミングを使用して作成していますので、私のコードでAVX2命令セットを使用します。アルゴリズムのバイトあたりの測定サイクル

Imは現在、私の実装がどれほど効果的かを正確に測定しようとしていますが、現在の数字は本当に信頼できません。私の現在の数字では、1バイトあたり約200サイクルが得られます。これは、暗号の上に何が得られるかわかりません。以下のために)(

は現在、私のコードは私が右の計算を行っております信じてこの

#typedef u64 unsigned long long 

u64 start, finish; 
u64 samples[1000000]; 
data = calloc(4000, sizeof(unsigned char)); 

//Performance test on a single core, as that is the standard when computing cycles/byte. 
SetThreadAffinityMask(GetCurrentThread(), 0x00000008); 

//Find CPU clock speed 
start = _rdtsc(); 
sleep(1000); 
finish = _rdtsc(); 
cpu_frequency = finish-start; 

//Take a lot of samples and use median of these. 
for (int i = 0; i < 1000000; i++){ 
    start = _rdtsc(); 
    encrypt(data); 
    decrypt(data); 
    finish = _rdtsc(); 
    samples[i] = finish - start; 
} 
qsort(samples); 
u64 median = samples[500000]; 
double cycles_per_byte = 1/(4000.00/median); 

のように見えるので、私は

  • が、それは間違った_rdtscを使用することです...思ったんだけど1バイトあたりの測定サイクル数は?
  • 私は自分のコードで費やされたクロックサイクルを測定するのではなく、システム全体で測定することができますか? (私のコードでどれくらい排他的に費やされているのか分かりませんが、わかりません)
  • Linuxは大きな違いがありますか?

GCCとMSVCの両方でコードをコンパイルしようとしましたが、違いはありませんでした(GCCは/ O2または/ O3と約1%速く、どちらが覚えていないか)。 Intel Turboboostを搭載した1つのコアでのみテストを実行しており、ハイパースレッディングはオフになっています。

私の完全なソースコードはここにある

:ビットスライスされた順列が、コードは今スーパークリーンではありません... Primate.cである私の悪いながら https://github.com/opolo/Bitsliced-AEAD/tree/master/Primates/APE120_Bitsliced 私のテストスイートは、Ref.cです。だからこそ私はコードを完全にc/pするのではなく、以前に例を挙げようとしたのです。

+0

'_rdtsc'がどのような措置を取るかは、非常に簡単です(https://msdn.microsoft.com/en-us/library/twchhe95.aspx)。 – molbdnilo

+0

こんにちは。答えをありがとう。私は_rdtscが何を測定したかは疑いませんでした。私がcpu_frequency変数を読んだ場合、その値がCPUクロックスピードと一致していることがわかりました。したがって、サイクルカウントでなければなりませんでした。私のサイクル/バイト数が他の暗号と比較して本当に大きいという事実は、私がそれを使うのが間違っていたのでは不思議でした。マルチコア環境で問題を引き起こす可能性がある場合、または私のコードに費やされたCPUサイクルを測定しないためでした(他の人がそうした場合には、他のサイクル/バイトコード測定を見つけることはできませんでした)。 Windows APIコール(_rdtsc()など) – oPolo

+1

速やかな健全性チェックを行うのは簡単です - 暗号でデータの大きなチャンクを処理します - 処理には10秒というオーダーの時間がかかりますあなたのデータのバイト数で割ります。これはあなたが正しいボールパークにいると頼ることができる数値を与えます - あなたの '_rdtsc'測定値と非常に異なる場合は、 –

答えて

2

バイト単位でサイクルを測定するには_rdtsc()を使用するのは間違っていますか?

これは正しい方法です。私はrdtsc命令のインラインアセンブリーを使用してインライン展開を保証します。これは実装に依存する関数なので、実際に何が起こっているのか分かりません。特に、アウトオブオーダー実行を正しく防止しているかどうかはわかりません。 here for an inline asm solutionを参照してください。私はx86の組み込み関数が何をしているのか分かりません。

なぜ私は自分のコードで費やされたクロックサイクルを測定するのではなく、システム全体で費やすことができますか?

はい、関数呼び出しにはオーバーヘッドがあります。通常、現代のプラットフォームにはO(100)クロックティックオーバーヘッドがあります。あなたのデータセットが十分に大きければ、本当に重要ではありません。

私はWindowsの代わりに実行することができますか。 Linuxは大きな違いがありますか?

いや


だから、アルゴリズムのうち、あなたが望むパフォーマンスを取得していませんか?これはすべてあなたの実装に依存しますので、私はバットからあなたのタイミング機能を責めません。アルゴリズムの実装を完成させるには多くの複雑さがあります。インラインasmまたは組み込み関数を使用して明示的にベクトル化したものを使用している場合は、標準Cおよび最適化されたコンパイラと比較してパフォーマンスが悪い、またはあまり抽象化されていない実装が悪い可能性があることに注意してください。良いアプローチは、まずベンチマークと検証としてアルゴリズムのC実装を記述し、次に手作業で最適化を開始することです。

暗号化/復号化機能はどこにありますか?

+0

非常に遅い答え - 申し訳ありません。その数ヶ月はかなりストレスでした。長い話が短い、あなたの答えは本当に私を助けて終わったので、感謝に値する:ありがとう!!私は私の論文のためにそれを必要としました。その答えに部分的に感謝したと言えるでしょう。私は_rdtsc()を使用して終了し、ちょうどあなたが提案する+私のデータセットを、速度の無視可能な小さな差異を作るために同じ操作を複数回行うほど大きくします。それはうまくいった! – oPolo

関連する問題