アセンブラ… (・∀・)イイ!
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNG機械語萌え。20 D4 FF FF 50 E8 8A DC FF FF 68 10 20 00 00 8D
45 B4 50 8D 85 B4 FB FF FF 50 6A 00 E8 7B DC FF
FF 8B E5 5D C3 00 00 00 FF FF FF FF 02 00 00 00
0D 0A 00 00 55 8B EC 83 C4 F4 84 D2 74 08 83 C4
F0 E8 82 C4 FF FF 89 4D F4 88 55 FB 89 45 FC 8B
45 FC 83 C0 04 8B 55 F4 E8 2B CD FF FF 8B 45 FC
80 7D FB 00 74 0F E8 B5 C4 FF FF 64 8F 05 00 00
00 00 83 C4 0C 8B 45 FC 8B E5 5D C3 55 8B EC 83
C4 F0 53 33 DB 89 5D F0 84 D2 74 08 83 C4 F0 E8
34 C4 FF FF 89 4D F4 88 55 FB 89 45 FC 33 C0 55
68 61 69 40 00 64 FF 30 64 89 20 8D 45 F0 50 8B
0153デフォルトの名無しさん
NGNG0154デフォルトの名無しさん
NGNG0155デフォルトの名無しさん
NGNG次の言葉のうち、どれか知っていますか:
アーキテクチャ、アドレス空間、レジスタ
0156デフォルトの名無しさん
NGNGすまんですな。
ちなみにあなたCPUのアーキテクチャとか頭に入ってる?
Linuxのカーネルソース読んだことある?
一般的なプロのプログラマーはどんなもんなんでしょうね。
自分はまだ学生ですが
0157デフォルトの名無しさん
NGNGpush ebp
mov ebp,esp
push FFFFFFFF
push 00406158
push 004038E8
mov eax,fs:[00000000]
push eax
とここまで来て思ったがintel8086ってスタックエリアに
定数そのままプッシュ出来たっけ?
0158デフォルトの名無しさん
NGNGCPUのアーキテクチャねぇ。
俺はアセンブラは趣味程度にしか弄らないから
一般教養程度しか頭に入ってないな。
名前以上のことを知ってるのは
IA-32、IA-64、68k、MIPS、SHぐらいか。
PowerPCやAlphaのことはまったく知らんな。
R2000とかだったら内部ダイアグラムを読むぐらいはできる。
でもあくまでも教養の範囲なんで
いきなり組み込み系の仕事をやれとかいわれても困る。
Linuxは触ったことない。ソースを一目見て反吐が出た。
どうでもいいが少し口の聞き方に気をつけた方がいいぞ。
0159デフォルトの名無しさん
NGNG何様のつもりだ。
0160デフォルトの名無しさん
NGNGdataはデータセグメント
bssは初期化されていないデータセグメント
データセグメントはスタックセグメントと重なる場合もある。(DS=SS)
セグメントは物理メモリをリニアに見た時の覗き窓で、
8086のレジスタ仕様の64kByteまでしか一度に(効率的に)
アクセスできない制限を緩和する役目をはたす。
64kというのは、レジスタの長さが16bitなので、65536バイトまで。
0161デフォルトの名無しさん
NGNG結構知っとるやんけ
自分はLinuxをメインに使っている
Linuxの全てを知り尽くしたい
それでカーネルソースというわけ
そのうちemacsとかxwindowのソースも読んでみたい
口の聞き方は直らんのでゆるせ
くるしゅうない
0162デフォルトの名無しさん
NGNGおいおい、セグメントって何だよ。
セクションだろ
0163デフォルトの名無しさん
NGNG直らないんじゃなくて、直そうとしないだけ.
0164デフォルトの名無しさん
NGNG0165デフォルトの名無しさん
NGNG0166デフォルトの名無しさん
NGNG0167デフォルトの名無しさん
NGNGアセンブラっていうのもね・・・
動くコードしかかけないじゃん
x86系じゃ、わかってても高速化は無理みたいだけど
ところで、インテルのコンパイラよりも最適化できる人って
いるの?
0168デフォルトの名無しさん
NGNGx86系じゃない人も
具体的にどこらへんを直した時に
どの程度早くなったのか教えてください
当然比較したコンパイラを書いてもらえないと、
かなり意味ないんですが・・・
0169デフォルトの名無しさん
NGNG動くコード以外に何を書くというのだ?
Intelのコンパイラもたいしたこと無い。
アレが完璧ならVTuneなんて売れるわけ無い。
つーか、VCよりも遅いこともあるし。
0170166
NGNG0171デフォルトの名無しさん
NGNG>160
補足すると
コンパイラが
text に コンパイルしたコードを吐く
data に static int x=0; みたいな変数を確保して かつ初期値を置く
bss には 初期化しなくていい変数を確保する
0172デフォルトの名無しさん
NGNG誰が読んでも、コンパイラよりも最適化されたコードって意味だろ
>Intelのコンパイラもたいしたこと無い
Pentiumに最適化するしたい時って・・・他に方法あるの?
で、Intelのコンパイラに問題があるなら
どのへんが問題なのか教えてくれよ
0173デフォルトの名無しさん
NGNG別に問題はないよ。
ただ、Intelのコンパイラが特別優れているというわけでもない。
0174デフォルトの名無しさん
NGNG>>動くコード以外に何を書くというのだ?
>誰が読んでも、コンパイラよりも最適化されたコードって意味だろ
それを言いたいのなら「動くコードしかかけない」ではなく
「動くだけのコードしかかけない」と書くべきだろ。
172の文も日本語的におかしいし駄目だこりゃ。
0175デフォルトの名無しさん
NGNGうわっ、とっても解りやすいです。
ありがとうございました。
0176デフォルトの名無しさん
NGNG0177デフォルトの名無しさん
NGNG>>157
それ 8086 のコードじゃ無いじゃない 386以後のコードだよね?
0178デフォルトの名無しさん
NGNG0179デフォルトの名無しさん
NGNG0180デフォルトの名無しさん
NGNG他のやつがソフトウエア工学をあまり知らなかったせいだと思われ
単なる動くコードっていうのは、
ソフトウエア工学でいう、まともな設計がなされてないコードの事
慣用表現のひとつだよ
0181デフォルトの名無しさん
NGNGじゃぁ、優良なコードは動くとは言わんのか?
ソフトウェア工学には 動くコード なんていう言葉の定義があるのか?
0182デフォルトの名無しさん
NGNGおい、あほまるだしだぞ?
0183デフォルトの名無しさん
NGNG0184デフォルトの名無しさん
NGNG「単なる動くコード」と「動くコード」では意味合いが違うぞ。
もったいぶらないで「動くだけのコード」とか書こうぜ?
0185デフォルトの名無しさん
NGNGアセンブラで作れますか?
0186デフォルトの名無しさん
NGNG802師匠に作ってもらうとイイ
0187デフォルトの名無しさん
NGNG0188デフォルトの名無しさん
NGNGこことってもいいのですがちょっと古めですよね。
似たようなアセンブラ初心者向けのページがあれば教えてください。
0189デフォルトの名無しさん
NGNG3日経つと古いのか?
0190七誌興奮型
NGNGCASL !! CASL !! CASL !! CASL !!
CASL !! CASL !! CASL !! CASL !!
CASL !! CASL !! CASL !! CASL !!
0192デフォルトの名無しさん
NGNGgas のニーモニックは NASM, MASM などとは違いますが、基本的に一対一に
対応します。変換規則も単純ですから、どっちで勉強しても良いです。
> セグメントとかページングとかはかなりの部分がx86がやってるらしいね
Linux の仮想記憶のコードは x86 アーキテクチャにべったり依存していて極めて
ダサい(他のアーキテクチャでは、頑張ってソフトウェアで x86 をエミュレートして
いる)ので、勉強のために読むのは薦めませんけど。
0194デフォルトの名無しさん
NGNGねーじゃねーかよ!!!
いかにマイナー言語かがわかるな。
0195デフォルトの名無しさん
NGNGアセンブラ以外でMMXのコード書いてくれよ
0196デフォルトの名無しさん
NGNG使う道具としてのアセンブラだけ で食うなら
1)DSPの類 ただしコーデング技術よりノウハウで食べるんだけどね
2)4ビット系 ただし競争相手は世界なんで・・・・
かな・・・ まあご飯食べたい為の仕事なら外の仕事がいいかも
0197デフォルトの名無しさん
NGNGホラヨ。今は組み込み関数でも書けるんだよ。
__m64 m1;
m1 = _mm_xor_si64(m1, m1);
ちなみに、IntelC/C++Compilerもしくは、
VisualC/C++ + VisualC/C++ ProcessorPackでコンパイル可能。
GCCとかも最近は似たようなのを搭載しつつある。
肝心の性能だが、MMXでは、
適当にインラインアセンブラで書いたコードよりは速いのを吐いてくれる。
アセンブラできちんとパイプライニングしたものよりは多少遅い。
SSEに関しては、はっきり言ってとりあえずインラインアセンブラで書いてみました
程度の投げやりなコードでもアセンブラの方が断然速い。
まだコンパイラが成熟してないのか。
ただし、組み込み関数といえど、ほとんどアセンブリとニーモニックなので、
速度を追求してかいていくと
__m64 mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7;
とかレジスタ分の変数用意して、それだけしか使わず、
パイプラインも考慮して書いたりとかするようになるから、
結局アセンブラで書いた方が楽だったりする。
0198デフォルトの名無しさん
NGNGホラヨ。今は組み込み関数でもかけるんだ。
__m64 m1;
m1 = _mm_xor_si64(m1, m1);
IntelC/C++Compilerまたは、
VisualC/C++ + VC ProcessorPackで使える。
最近は、GCCとかでも似たようなのを実装しつつあるらしい。
気になる性能のほうは、
MMXに関しては、何も考えずに適当に書いたインラインアセンブリのコードよりは
高速なコードを吐き出してくれる。
ちゃんとパイプライニングしたアセンブリコードの方が少し速い。
SSEに関しては、はっきり言って何も考えずに書いたアセンブリコードの方が
大分高速に動作する。まぁ、どうしてもアセンブリが理解できない人向け?
この手の組み込み関数使ってても、
速度を追求して逝くと、結局はレジスタの数とか
ニーモニックとの対応やパイプラインを考えていくと、
ほとんどアセンブラと変わらん内容になってしまうので、
あんまり使い物にならんが。
0199197==198
NGNGちゃんと書き込めてたのか。2重投稿(しかも微妙に内容違う)スマソ。
0200デフォルトの名無しさん
NGNGインテルコンパイラに入ってる ivec.h なんかのベクタクラスライブラリを使うと
Is16vec4 m1; // 16bit符号付き整数×4
m1 = m1 ^ m1;
こんな風に直感的に書けるね。
0201197
NGNGそだね。でも、所詮は↑の組み込み関数のラッパーに過ぎないから、
直で組み込み関数使った方が実行速度は速いかな?
あと、実際には同じmmレジスタを8bitx8で扱ったり16bitx4で扱ったりとか
する場面が結構出てくるから、そういうときベクタクラスだとやりにくいかも。
02021
NGNGアセンブラスレに飢えていたのか?
0203デフォルトの名無しさん
NGNGなんでやねん!!
0204デフォルトの名無しさん
NGNG入門以前の事について書いてるページとかないよね
0205デフォルトの名無しさん
NGNGDOSでって、16ビットコンパイラの話をしているのか?
0206デフォルトの名無しさん ?
NGNG秋月で買い物すればいいような気が。
0207デフォルトの名無しさん
NGNGふつーにOBJファイルを生成したあとにリンクさせればいいじゃn
0208デフォルトの名無しさん
NGNGpublic
_
呼び出し規約
とか、その辺?
0209デフォルトの名無しさん ?
NGNG「MASMと…コンパイラをリンク」って書いてあるから
オブジェクトファイルをリンクさせるのとは
違う意味らしいよ。
>>204
Makefile を作っておいて、
nmake に Makefile を食わせればよい。
「入門以前」というより、ビルドを速くやるための浦和座というか…
裏技かよ?>漏れ
0210デフォルトの名無しさん
NGNGまず日本語入門サイトを探せ
0211204
NGNG>209
そうなんです、それなんです。
でもlink.exeが上手く動かずに必ずエラーが出るんです。
C++をvcvars32やってDOSで使ってたんですが、DOSではclしかできないんでしょうか…
>210
すみません。
プログラム始めたばかりなので質問しようにも知識が足りなくて。
0212デフォルトの名無しさん
NGNGなぜloop1の方が速いのでしょうか?
命令数はLoop2の方が少ないのに。
loop1は↓にあります。
http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=049229
@@loop1:
MOVZX EAX, byte ptr [ESI]
MOVZX EBX, byte ptr [ESI+1]
MOV DL, byte ptr [EDI + EAX]
MOV DH, byte ptr [EDI + EBX]
MOV byte ptr[ESI], DL
MOV byte ptr[ESI+1], DH
DEC ECX
LEA ESI, [ESI + 2]
JNZ @@loop1
@@Loop2:
mov ax, [esi]
mov ax, [edi + eax]
mov [esi], da
add esi, 2
dec ecx
jnz @@Loop2;
0213デフォルトの名無しさん
NGNG?
loop2のdaってなんだ?
あと、処理が全然等価に見えないのだが?
俺がバカなだけか?
しいて言うならloop2はPpro系(Ppro,P2,P3等)のCPUだと部分レジスタストールに
該当するので遅くなる
あとloop2は486とクラシックPentiumでアドレス生成インターロックも
発生するかな?
Pproの部分レジスタストールは確か5クロックぐらいだったと思うので
JNZを除くloop1のクロック数が8として
同様にJNZを除くloop2のクロック数がまぁ見えてる範囲で9クロックだな
P2、P3のみに限ればloop1は十分な速度だ
それ以外のcpuも考慮する場合は
MOVZX EAX, byte ptr [ESI]
MOVZX EBX, byte ptr [ESI+1]
を
XOR EAX,EAX
MOV AL, byte ptr [ESI]
XOR EBX,EBX
MOV BL, byte ptr [ESI]
にするべきだ
まぁなんにしろ>212よ
お前にはアセンブラは向かないから理解するのを諦めろ
0214213
NGNGMOV BL, byte ptr [ESI]→MOV BL, byte ptr [ESI+1]
逝ってくるわ
0215デフォルトの名無しさん
NGNGediには64KB(256x256)の置換テーブルがあるってことかな。
これによるキャッシュ溢れも原因かもね。
loop1もloop2もそうだけど、1ループあたりの処理データ量が少ないなあ。
一回分ぐらいはunrollしてもいいと思うけど。
0216212
NGNGaxの間違いでした。
>処理が全然等価に見えないのだが?
リンク先を見れば分かりますが、
loop1は1バイトX256個 のテーブルを使っています。
そこで
loop2では2バイトX65536個のテーブルを使ってやってみたのです。
Delphiのコードはこんな感じです。
// Sの長さは偶数とする。
procedure Test7(var S : string );
var
ConvTbl: array[Word] of Word;
I: Integer;
P: PWord;
begin
for I := low(ConvTbl) to High(ConvTbl) do
ConvTbl[I] := I;
ConvTbl[PWord(PChar('AC'))^] := PWord(PChar('CA'))^;
// スキップ...
P := Pointer(PChar(S));
for I := 1 to length(S) div 2 do
begin
P^ := ConvTbl[P^];
Inc(P);
end;
end;
0217212
NGNGTest8(下のソース)を20回ぐらい連続して呼び出すと、
Test6と同じぐらいの速度になりました。
さっぱり分かりません。 Test6は↓にあります。
ttp://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=049229
procedure Test8(var S : string );
var
ConvTbl: array[Word] of Word;
I, Count, Len: Integer; P: PWord;
begin
for I := low(ConvTbl) to High(ConvTbl) do ConvTbl[I] := I;
ConvTbl[PWord(PChar('AC'))^] := PWord(PChar('CA'))^;
ConvTbl[PWord(PChar('AT'))^] := PWord(PChar('TA'))^;
ConvTbl[PWord(PChar('AG'))^] := PWord(PChar('GA'))^;
ConvTbl[PWord(PChar('CA'))^] := PWord(PChar('AC'))^;
ConvTbl[PWord(PChar('CT'))^] := PWord(PChar('TC'))^;
ConvTbl[PWord(PChar('CG'))^] := PWord(PChar('GC'))^;
ConvTbl[PWord(PChar('GA'))^] := PWord(PChar('AG'))^;
ConvTbl[PWord(PChar('GC'))^] := PWord(PChar('CG'))^;
ConvTbl[PWord(PChar('GT'))^] := PWord(PChar('TG'))^;
ConvTbl[PWord(PChar('TA'))^] := PWord(PChar('AT'))^;
ConvTbl[PWord(PChar('TC'))^] := PWord(PChar('CT'))^;
ConvTbl[PWord(PChar('TG'))^] := PWord(PChar('GT'))^;
P := Pointer(PChar(S));
Count := Length(S) div 2;
asm
pusha
mov ecx, Count
mov esi, P
lea edi, ConvTbl
xor eax, eax
@@Loop:
mov ax, [esi]
mov ax, [edi + eax]
mov [esi], ax
add esi, 2
dec ecx
jnz @@Loop
popa
end;
Len := Length(S);
if not Odd(Len) then
begin
case S[Len] of
'A': S[Len] := 'T';
'T': S[Len] := 'A';
'G': S[Len] := 'C';
'C': S[Len] := 'G';
end;
end;
end;
0218212
NGNG>Test6と同じぐらいの速度になりました。
毎回違う文字列でテストしたら、Test8は速くなりませんでした。
0219212
NGNG>ediには64KB(256x256)の置換テーブルがあるってことかな。
Loop1は256バイトの置換テーブルです。
Loop2は64K*64Kバイトの置換テーブルを用意して、
2バイトづつ置換しています。
0220213
NGNGデカイテーブルをボトルネックになる関数内で作ってりゃ世話がない
アセンブラ以前の問題だ
あと128kのテーブルはキャッシュあふれする可能性が高い
というかあふれるだろ
テーブルはでかけりゃいいってモンじゃないぞ
CPUの1次キャッシュや2次キャッシュに巧く乗るように(極力1次キャッシュに乗るように)
してメモリ読込による遅延を隠蔽してやらんと場合によっちゃCPU演算した方が早くなるぞ
あとアセンブラ箇所のみ関しては部分レジスタストールしてるつってんだろ
それだけ聞いてわかんなかったら諦めろ
お前にはアセンブラは向いてないって言ってるだろ?
どうして『部分レジスタストール』でgoogle引くぐらいしないんだよ?
取り合えずfnami氏のHPでも見てこい
ttp://www.csl.sony.co.jp/person/fnami/asm.htm#PARTIAL
ttp://www.csl.sony.co.jp/person/fnami/asm.htm#STALL
CPUにもよるがちゃんと今のx86で手動最適化する技能を持った人間は
お前みたいなペアリング無視ペナルティー無視のコードは書かない
最近のCPUは短いコードを書けば速くなるわけじゃないんだよボウヤ
(無論無意味に長いのは問題外だが)
0221212
NGNG部分レジスタストールについては今やっています。
220さんありがとうございます。
0222212
NGNGxor eax, eax
mov ax, [esi]
mov ax, [edi + eax]
これだけで部分レジスタストールは回避されるのでしょうか?
0223213
NGNG実はCPUがクルーソーとかいうオチを期待しているぞ(藁
>222
まぁ部分レジスタストールしてるのはそこだけだね
ただレジスタ衝突もしてるんで
@@Loop:
mov ax, [esi]
mov ax, [edi + eax]
mov [esi], ax
↓
@@Loop:
xor eax,eax
mov ax, [esi]
mov bx, [edi + eax]
mov [esi], bx
とするべき
対象CPUがP2以降ならAGIストールは発生しなかったはずなんで
AGIストールは無視する?
番地をレジスタに生成直後にその番地へアクセスするとストールする<AGIストール
上記なら
mov ax, [esi]
mov bx, [edi + eax] <ここでAGIストール
となる
なのでまずこういうコードは書かないよ<真にチューニングするべきルーチンでは
0224デフォルトの名無しさん
NGNGプログラム/テーブル/入力文字列/出力バッファ
の全てが1次あるいは2次キャッシュに乗るからでないの?
テーブルは全体でなく、
入力文字列を処理するのに必要な分だけ乗ればいいことに注意。
0225213
NGNG(asm部分では考えうる限り最速のチューニングしてるよ
逆に言うとloop2をloop1に近い形にもっていくのが速度の秘訣だ)
あ〜ebpまで使えばなんとかなるかな?>loop2でも
Count := Length(S) div 4;
asm
pusha
mov ecx,Count
mov esi,P
lea edi,ConvTbl
mov ebp,ecx
@@Loop:
xor eax,eax
mov ax,[esi]
xor ebx,ebx
mov bx,[esi+2]
mov dx,[edi+eax]
mov cx,[edi+ebx]
mov [esi],dx
mov [esi+2],cx
add esi,4
dec ebp
jnz @@Loop
popa
end;
つーかdec ebpって美しくないなぁ(´Д`;)
4byte/10クロックでペナルティーは見受けられないから
loop1の2byte/8クロックよりは速いかな(ただし要大容量キャッシュ)
はっきり言ってアレだけど真面目な話
コンパイラの最適化に任せるべきだよ>212君
ペアリングとレジスタ衝突、様々なペナルティーとキャッシュ周りを
きっちり考えて最適化しないと逆に遅くなるからね>今のCPUは
コンパイラはその辺考えたコード結構吐いてくれるんで
現行のCPUに関する詳しい知識がないならアセンブラによる最適化はお奨めできないよ
0226デフォルトの名無しさん
NGNG0227デフォルトの名無しさん
NGNG0228213
NGNG実質的なチューニング的には殆ど終わったも同然でしょ?>loop1
0229デフォルトの名無しさん
NGNGそれに、こういう場面じゃアセンブラで書いても 頑張っても2〜3倍程度しか
変わらない。
同じ時間を割くなら もっと生産的な部分に注力した方がいいと思うな
それでも、どうしてもなんとか高速にしたいなら PCMPEQBで8バイト
同時に比較してはXOR・ANDマスクして置換すれば・・・・うーん
でも英大文字を英小文字にするとか一方向置換にしないといけないし
1ループで4回の置換作業が必要だから 速くなるかどうか判らないな
0230213
NGNG漏れも思って取り合えず考えはしてたんだが余計遅くなった(´Д`;)>pcmpeqb
movq mm0,[esi]
movq mm1,mm0
movq mm2,mm0
pcmpeqb mm1,mm4
pcmpeqb mm2,mm5
pand mm1,mm5
pand mm2,mm4
por mm1,mm2
movq mm3,mm1
movq mm1,mm0
movq mm2,mm0
pcmpeqb mm1,mm4
pcmpeqb mm2,mm5
pandn mm1,mm0
pandn mm2,mm0
por mm1,mm2
por mm3,mm1
movq mm1,mm3
movq mm2,mm3
pcmpeqb mm1,mm6
pcmpeqb mm2,mm7
pand mm1,mm7
pand mm2,mm6
por mm1,mm2
movq mm0,mm1
movq mm1,mm3
movq mm2,mm3
pcmpeqb mm1,mm6
pcmpeqb mm2,mm7
pandn mm1,mm3
pandn mm2,mm3
por mm1,mm2
por mm0,mm1
movq [esi],mm0
add esi,8
dec ecx
色々突っ込みどころ満載な上に動作確認もしてないんで
これに関する言及は勘弁してくれ(取り合えず並べただけなんで
最大の敗因は文字列に4本も使ってしまいmmxレジスタが足りなくなったことだ……
0231pcode 本人
NGNGもう一度アンロールしても手間の割には早くならない。
「アセンブラで書けば速くなる」という迷信を砕くのが目的だった
から、アセンブラグルの方々、212 の無知を許してやってくれや。
0232デフォルトの名無しさん
NGNG最近では「P4はSSE2最適化すれば何でも速くなる」と思っている人が多い。
0233197
NGNGある意味真でもあるんぢゃない?
少なくとも浮動小数点演算に関しては、
x87命令つかうよりもSSE/SSE2のスカラ演算命令の方が速いと
インテルが主張していたような。
その証拠(?)に、インテルのコンパイラには、浮動小数点演算を
x87命令を使わずにSSE/SSE2のスカラ命令を使うってオプションがついてた。
ちなみに、Pentium!!!で試したところ、実行速度に差違は見られなかった。
誰かPentium4で試してみてよ。
0234デフォルトの名無しさん
NGNG>x87命令を使わずにSSE/SSE2のスカラ命令を使うってオプションがついてた。
そんなオプションないよ。
x87とSSE/SSE2を併用するというオプションはあるけど。
またx87,SSE/SSE2併用オプションでコンパイルしてもほとんど速くならないケースは多い。
あとP4の場合、SSE/SSE2スカラの加算命令は、2クロック毎に1つしか実行できないから、
x87の加算命令の半分のスループットしか出ない。
0235229
NGNG1回の交換が
1) @1 := @0 XOR "AAAAAAAA"
2) @2 := @0 XOR "TTTTTTTT"
3) @3 ;= pcmpeqb(@1,all0)
4) @4 ;= pcmpeqb(@2,all0)
5) @2 := @2 AND @3
6) @1 := @1 AND @4
7) @1 := @1 OR @2
8) @0 := @0 XOR @1
でこれが1ループで2回必要だから、やっぱり改善にはならないかもねえ
0236229
NGNGmovq mm0,[eax]
movq mm1,mm0
movq mm2,mm0
pXOR mm1, qword ptr tblA
pXOR mm2, qword ptr tblT
movq mm3,mm1
movq mm4,mm2
pCMpeqB mm3,qword ptr tbl0
pCMpeqB mm4,qword ptr tbl0
pAND mm2,mm3
pAND mm1,mm4
pOR mm1,mm2
pXOR mm0,mm1
{ 略 tblA/tblT のみ置換して繰り返し}
movq [eax],mm0
tblAは'A'が8バイト続くデータ tbl0は値0のqwordデータ
0237229
NGNGちょっと短くなった
procedure ATCGchg8( p:PChar;cnt:integer);
const tblA:array[0..7] of Char=('A','A','A','A','A','A','A','A');
const tblT:array[0..7] of Char=('T','T','T','T','T','T','T','T');
const tblG:array[0..7] of Char=('G','G','G','G','G','G','G','G');
const tblC:array[0..7] of Char=('C','C','C','C','C','C','C','C');
const tbl0:array[0..7] of byte=($00,$00,$00,$00,$00,$00,$00,$00);
label lp;
asm
movq mm0, qword ptr tbl0
movq mm6, qword ptr tblA
movq mm5, qword ptr tblT
movq mm4, qword ptr tblG
lp:
movq mm7,[eax]
movq mm1,mm7
movq mm2,mm7
pXOR mm1, mm6
pXOR mm2, mm5
movq mm3,mm1
pCMpeqB mm3,mm0
pAND mm3,mm2
pCMpeqB mm2,mm0
pAND mm1,mm2
pOR mm1,mm3
pXOR mm7,mm1
movq mm1,mm7
movq mm2,mm7
pXOR mm1,mm4
pXOR mm2, qword ptr tblC
movq mm3,mm1
pCMpeqB mm3,mm0
pAND mm3,mm2
pCMpeqB mm2,mm0
pAND mm1,mm2
pOR mm1,mm3
pXOR mm7,mm1
movq [eax],mm7
dec cnt
lea eax,[eax+8]
jnz lp;
end;
呼び出し方
var buf:string;
begin
buf:='AGCT AGCT AGCT AGCT AGCT AGCT';
SetLength(buf,length(buf)+(8-length(buf) mod 8) );
ATCGchg8(@buf[1],length(buf) div 8);
0238197
NGNG漏れの記憶違いか……?
確認のため、なんとか発掘した
v4.5の日本語マニュアルにはこう書いてあった。
>-Qkscalar デフォルトのx87 命令でなく、
>ストリーミングSIMD 拡張命令を
>使用して、すべての32 ビット浮
>動小数点演算を実行します。
日本語訳が間違えているのかもしれないが、
英語のドキュメントどっか逝ってしまって見つけ出せなかったので確認できず。
ちなみに、v5.0のドキュメントを見たら、-Qkscalarは載ってなかった。
0239212
NGNGmov ax, [edi + eax] → mov ax, [edi + eax * 2]
テーブルの計算方法は間違っていました。
type
TWordTable = array[Word] of Word;
procedure SetWordTable(var Table: TWordTable);
var
I: Integer;
H, L: Char;
begin
for I := 0 to $FFFF do
begin
H := Char(Hi(I));
L := Char(Lo(I));
case H of
'A': H := 'T';
'T': H := 'A';
'C': H := 'G';
'G': H := 'C';
end;
case L of
'A': L := 'T';
'T': L := 'A';
'C': L := 'G';
'G': L := 'C';
end;
Table[I] := MakeWord(Byte(L), Byte(H));
end;
end;
0240212
NGNG>純粋にキャッシュヒットしてるんじゃないか?>連続呼び出し
そのようでした。 同じ文字列(同じメモリブロック)がキャッシュに
入っていたみたいです。 UniqueStringで別のアドレスに確保すると、
速くなりませんでした。
AGIストールについても考えてみます。
ありがとうございます。
部分レジスタストールについて質問なのですが、
下の(1)と(2)で発生するのでしょうか?
mov ax, 0
inc ecx
mov ecx, eax // (1)直後でない
@@Loop:
mov ecx, eax // (2)ループ
mov ax, 0
jmp @@Loop
0241212
NGNGhttp://www.sonycsl.co.jp/person/fnami/pentopt.htm#PPRO
の例で
MOV AL, [mem1] 1 uv
MOV AH, [mem2] 1 uv
MOV [mem3], AX 1
2 + 5(ペナルティー) = 7 clock
MOVZX EAX, BYTE PTR [mem1] 3
MOVZX EBX, BYTE PTR [mem2] 3
SHL EBX, 8 1 u
OR EAX, EBX 1 uv
MOV [mem3], AX 1
8 clock
なので、遅くなりませんか?
これは次のように変更するべき
でブラウザを検索すると見つかります。
0242213
NGNGん〜(1),(2)ともしないと思うけど?
>241
Pentiumでは部分レジスタストールは発生しないよ?
もうチョッとよく読もうな
そこでの記載はPentiumProとPentium2(3)に関してだし
Ppro系CPUではMOVZXは1クロックだよ(P4では0.5クロック)
μopコード実行だからペアリングなんて概念自体が無いので>Ppro
逆にPentiumではmovzxは重い処理になるのでやるべきじゃない
・Pentium
MOV AL,[mem1];1uv
MOV AH,[mem2];1uv
MOV [mem3],AX;1
2クロック
MOVZX EAX,BYTE PTR [mem1];3
MOVZX EBX,BYTE PTR [mem2];3
SHL EBX,8;1u
OR EAX,EBX;1uv
MOV [mem3],AX;1
8クロック
・PentiumPro
MOV AL,[mem1];1
MOV AH,[mem2];1
MOV [mem3],AX;1+5
約8クロック
MOVZX EAX,BYTE PTR [mem1];1
MOVZX EBX,BYTE PTR [mem2];1
SHL EBX,8;1
OR EAX,EBX;1
MOV [mem3],AX;1
約5クロック
どっちのCPU向けに最適化するかによる
今時だとP2、P3が主流だと思うんでPpro向けの最適化のほうが好ましいと思う
Pentiumでの遅延を減らしたいなら
movzx eax,[mem]→xor eax,eax/mov al,[mem]
に展開するべき(さもなくばCPUによってル−チンを切り替えるか)
ちなみにP4だと何故か展開したほうが速くなるんだよね……>movzx
0243デフォルトの名無しさん
NGNG0244デフォルトの名無しさん
NGNG真の乱数(規則性なし)は量子コンピュータ持ってきても作れませんが、何か……?
量子力学やカオス理論の世界ですら、
時間をパラメータとする規則性のある数列でしかないことがわかってるし。
自然界では時間は任意に変更できないから、
ある意味真にランダムであるとも言えるだけで。
つーか、ランダム性と処理速度とどっちを重視するのか言ってくれないと、
紹介のしようもない。
0245Delあめ猫にゃ
NGNG乱数種の一つとして
function RDTSCm:integer;
asm
DW $310F //RDTSC
XOR EAX,EDX
IMUL EAX,65535
end;
0246デフォルトの名無しさん
NGNG最近のPCならチップセットに乗ってる
ハードで完全にランダムな値、作れるんじゃないの?
漏れのマシンにはついてないけど。
http://developer.intel.com/design/chipsets/rng/faq.htm
レジスタ叩いて読むだけ。
>>244さんはこれでも満足できないのかもしれないけど
ソフトでやるのでは、回数が少なければ、
サイコロ振って乱数表作ってメモリに入れとけば、
規則性のない乱数列が作れるんじゃない。
周期性は避けられないが。
0247デフォルトの名無しさん
NGNGシリアルポートにでもつなげ
0249デフォルトの名無しさん
NGNG24bit以上のデータを扱えるオーディオカードならな。
普通のサウンドカードだと、16bit、しかも低い値しか取れないから、
拡大すると荒い乱数しか取れない。
0250212
NGNG215さんも224さんもありがとうございます。
キャッシュが・・・、と言われていたのに・・・。
0251デフォルトの名無しさん
NGNG例えば32bitの乱数が欲しければ、サンプルの下位1bitだけを
使用するとして32個サンプリングすればよいんじゃないの?
(本当はもっと偏りがないようにうまくやったほうが良いが)
これなら16bitサウンドカードでも大丈夫だ。24bitのサンプル1個を
そのまま乱数に使うってのは頭が悪いとしか思えん。
0252デフォルトの名無しさん
NGNG速度が遅くなんない?
どのぐらいかかるか知らないけど
■ このスレッドは過去ログ倉庫に格納されています