問題タブ [rdtsc]
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.
linux - Intel Celeron 64 ビット アセンブリ プログラムの RDTSC
RDTSC を使用してランダム性を与える小さな乱数プログラムを作成しました。Linux Mint 17 で FASM を使用して作成しました。
問題は、AMD FX 64 ビット PC では完全に動作しますが、Windows 8 と Linux Mint (私はデュアル ブートなので、 Win 8 のコード)
ここで何が問題になる可能性がありますか?これが基本的なコードです。
デバッグしたところ、コードのこの部分に犯人が隠れていることがわかりました。しかし、私も何の問題も見ません。私のAMD PCで完璧に動作します。Intel CPU では RDTSC はデフォルトで無効になっていますか?
performance - 関数を測定するための rdtsc タイミング
rdtsc で関数呼び出しの時間を測定したい。そこで、以下の2つの方法で測定しました。
- ループで呼び出します。ループ内の各 rdtsc 差を集計し、呼び出し数で割ります。(これをNとしましょう)
- ループで呼び出します。ループ自体の rdtsc 差を取得し、N で割ります。
しかし、一貫性のない動作がいくつか見られます。
- N を増やすと、方法 1 と 2 の両方で時間がかなり単調に減少します。方法 2 の場合、ループ制御のオーバーヘッドが償却されるという点で理解できます。しかし、方法1の場合はどうなるかわかりません。
- 実際、方法 2 では、N を増やすたびに、N=1 の値が毎回新しい N で割られているように見えます。gdb の逆アセンブルを調べると、2 番目のケースでループがスキップされる -O2 でのコンパイラの最適化であることがわかりました。そこで、-O0 を使用して再試行しました。ここで、gdb 逆アセンブリは、2 番目のケースでも実際のループが存在することを示しています。
コードを以下に示します。
ここで何が起こっているのか分かりますか?必要に応じて、gdb 逆アセンブリも配置できます。http://dasher.wustl.edu/tinker/distribution/fftw/kernel/cycle.hの rdtsc 実装を使用しました
編集: 2 番目のケースでは、-O0 で時間が N に正比例して減少するという 2 番目のステートメントを撤回する必要があります。ビルド中に犯した間違いが原因で、古いバージョンが残っていると思います。どのようにしても、方法 1 の図に沿っていくらか低下します。異なる N 値の数値を次に示します。
現在、2 つの新しい動作が見られます。
- 方法 1 は、方法 2 よりも収束が遅くなります。しかし、異なる N 設定の値になぜこのような劇的な違いがあるのか について、私は困惑しています。おそらく、現時点では見られないいくつかの基本的な間違いをここで行っています。
- 方法 1 の値は、実際には方法 2 よりもいくらか大きくなっています。ループ制御のオーバーヘッドが含まれていないため、方法 2 の値と同等かそれよりわずかに小さいと予想しました。
質問
要約すると、私の質問は
Nを増やすと、両方の方法で得られる値が大幅に変化するのはなぜですか? 特に、ループ制御のオーバーヘッドを考慮しない方法 1 の場合。
最初の方法が計算でループ制御のオーバーヘッドを除外しているのに、2 番目の方法の結果が最初の方法の結果よりも小さいのはなぜですか?
編集 2
推奨されるrdtscpソリューションについて。
インラインアセンブリに慣れていないので、次のことを行いました。
関数呼び出しの前後に上記のメソッドを使用します。しかし、今では次のような無意味な結果が得られます。
キャッチは何ですか?複数の場所で使用されているため、それらをインラインメソッドとして除外したかったのです。
A. コメントの解決策。
c++ - Intel 以外のコンパイラの mkl_get_clocks_frequency() と同等
_rdtsc()
Intel コンパイラでタイムスタンプ カウンターを取得するために使用します。_rdtsc()
と組み合わせて使用してmkl_get_clocks_frequency()
、タイムスタンプカウンターの読み取り値を秒に変換します。どちらも Intel コンパイラに固有のものです。
一方、_rdtsc()
インライン アセンブリを使用する GNU コンパイラには同等のものがありますが、同じものはありませんmkl_get_clocks_frequency()
。
ポータブルな方法で CPU クロックレートを推定するにはどうすればよいですか?
c++ - コアIDを返さずにrdtscp()?
次のQを読んでいました。
rdtscp の正しいインライン アセンブリ コードはどれですか?
ここで、呼び出す次の C++ について説明しますrdtscp
。
ただし、コア ID を返すことに関する ECX と問題に関する議論があります。コア ID に興味がなければ、上記を変更してrdtscp
呼び出しのオーバーヘッドやレジスタへの影響を減らすことはできますか?
c++ - このアセンブリ タイムスタンプ関数を C++ に変換するにはどうすればよいですか?
他の人のプロジェクトを 32 ビットから 64 ビットに変換しようとしています。x64 のビルド時に Visual Studio でサポートされていないアセンブリ式を使用する 1 つの関数を除いて、すべて問題ないようです。
これについて最も面白い点は、これが乱数の生成に使用されていることです。どちらasm
のブロックも x64 ではコンパイルされないため、いじってifdef
も役に立ちません。プログラム全体を書き直さないように、C/C++ の代替を見つける必要があります。
rdtsc - cpuid + rdtsc とアウトオブオーダー実行
cpuid
rdtsc
単独で使用すると、ベンチマークされた命令の実行が前に並べ替えられる可能性があるため、ベンチマーク時に ooo の実行を防ぐためのシリアル化命令として使用されます。私の質問は、以下の手順を と の間でrdtsc
並べ替えることがまだ可能かどうかです。はシリアライズ命令ではないので、命令を自由に並べ替えることができますか?cpuid
rdtsc
rdtsc
delphi - Delphi - Int64 で 2 つの整数を結合します
私は と で作業しているDelphi
のでAssembly
、問題がありました。RDTSC
64 ビット読み取りタイムスタンプを取得するアセンブリでinstruction( ) を使用しました。この命令は、数値を 2 つのレジスタEAX
とに別々に配置しますEDX
。でも大丈夫です、Delphi Integer
変数で取得します。しかし今、これらの変数を 1 つの 64 ビットに結合する必要があります。それは次のようなものです:
だから私はそれを次のような1つの変数に入れる必要があります:
StrCat のようなものですが、やり方がわかりません。誰かが私を助けることができますか?
assembly - RDTSC (プロファイリング) NASM 構文を使用すると、毎回値が増加します
NASM と AFD デバッガーを使用して 8086 コードをプロファイリングしようとしています。RDTSC(0x0f31) 命令を使用しようとしていますが、古いタイム スタンプから新しいタイム スタンプを減算して取得した値は非常に大きく、常に増加しています。何が問題なのかわからない。コードは次のとおりです。
assembly - rdtsc を使用して Qemu i386 システムでベンチマークする方法
現在、同じ環境で 2 つの異なるプログラミング言語による操作を完了するのにかかるクロック サイクル数を測定しようとしています。(OSを使用しない場合)
現在、Qemu-i386エミュレーターを使用しており、rdtscを使用してクロックサイクルを測定しています。
動作前後の rdtsc の差を取ると、クロック サイクル数が得られます。
しかし、数百回以上の繰り返しを行っても、その差は一定ではなく、数千サイクルごとに異なります。
クロックサイクルを測定するより良い方法はありますか?
また、Qemu の入力パラメーターとして周波数を提供する方法はありますか? 現在、私は使用しています
qemu-system-i386 -kernel out.elf
gcc - アセンブラ命令: rdtsc
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.htmlで指定されたアセンブラを理解するのを手伝ってくれませんか
こんなふうになります:
それはどのように違うのですか:
なぜシフトおよびまたは操作が必要なのですか? また、最後の rdx は何をしますか?
編集:元の質問にまだ不明な点を追加しました。
- "\n\t" は何をしますか?
- ":" は何をしますか?
- 区切り文字出力/入力/クロバー...
- 最後の rdx は 0 ですか?
要約するだけです。最初の行は、レジスタ eax および edx にタイムスタンプをロードします。2 行目は値を eax にシフトし、rdx に格納します。3 行目では、edx の値と rdx の値を ors し、rdx に保存します。4 行目は、rdx の値を変数に割り当てます。最後の行は rdx を 0 に設定します。
- 最初の 3 行に「:」がないのはなぜですか?
- それらはテンプレートです。":" を含む 1 行目は出力、2 行目はオプションの入力、3 行目はクロバー (変更されたレジスター) のオプション リストです。
- a は実際には eax と d - edx ですか? これはハードコードされていますか?
再度、感謝します!:)
EDIT2:私の質問のいくつかに答えました...