トップページ⇒tech
140コメント60KB

アセンブラに関するマジ質問だけど

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
今、半透明ってやつをやってるんだけど。256色の。
どうにも速度が出ないんだよね・・・・
下に俺のソースの抜粋書くから、
わかる人は教えてくれないかな・・・?
0090デフォルトの名無しさんNGNG
みんな、もっとスタックフレームを使おうぜ。

今後はますます平行処理出来る事をCPUにどう知らせるかが高速化の
決め手になるんだからさ
0091デフォルトの名無しさんNGNG
スタックアドレスの前後がレジスタに割り当てられるCPUがあるね
0092デフォルトの名無しさんNGNG
>>88
>SSE使っていいなら、prefetch命令を最内周ループの
>先頭に入れて、次のループ分をキャッシュに入れちゃうとか

とりあえず、ダミーで最内周ループ先頭に
mov al,[esi+4]
mov al,[edi+4]
って入れちゃえばいいんじゃない?
実際に入れてみるとちょっと速くなるみたい。
0093デフォルトの名無しさん NGNG
>>73
ESPもあるぞ
009464NGNG
>>92
P6の場合キャッシュ1ラインは32Bytesなので、32Bytes置きでOK。
よって、サイズにもよるけど、Yのループでやる方が良いかもね。
0095デフォルトの名無しさんNGNG
既に6クロックで1ドット処理出来てるなら 640x480ドット処理しても
100Mのマシンでも1秒50フレームは処理出来るじゃないか

いったいなぜ不満が?
009679NGNG
そうか、そんなに早くなかったのか・・・・
昔は読み書き回数 減らせばそれだけ早くなった
んだけどなあ・・・というか最近最適化なんてやってないな
0097#6411NGNG
漏れがDirectDrawで半透明処理やってたときは、
ターゲットがMMXなP55Cだったけど、いかに1次キャッシュの上で
処理を完結させるかがキモだったような気もしたり。
バリバリ半透明合成やっても、20fpsくらいは出てたぞ〜
VTuneのトライアル版にだいぶお世話になったがの。
0098デフォルトの名無しさんNGNG
>>96
P6の場合、整数演算実行ポートとロード・ストア実行ポートが別々になっているので、
1次キャッシュにヒットするロード・ストアは有効に使った方がいい場合がある。
無理にレジスタのみで処理しようとすると、整数演算実行ポートばかりが飽和してしまい、
ロード・ストア実行ポートはガラ空きという、もったいない状況になる場合がある。
0099デフォルトの名無しさんNGNG
半透明合成で20FPSってぜんぜん自慢にならん(´д`;)
ま、用途にもよるか。
# demoならOK。ADVゲームならOK。アクションなら×ってか。
010064NGNG
>>99
でもP55Cの時代だしね。
解像度にもよるけどまぁまぁなんじゃない?
0101デフォルトの名無しさんNGNG
MMX命令とは使えばもっとはやくなるんじゃないの?
0102デフォルトの名無しさんNGNG
>>101
MMXはテーブルにアクセスできないからね。
このアルゴリズムではMMXは使えない。
テーブルが簡単なものであれば、テーブルを使うのをやめて地道に計算→MMX化はできるけど、
テーブルが複雑なものであれば無理。
0103デフォルトの名無しさんNGNG
パレットではどーにもならん>MMX
0104デフォルトの名無しさんNGNG
L R1,0(,R1)
LH R0,0(,R1)
LTR R0,R0
BZ ABEND
BCTR R0,0
STC *+5
MVC PARMSTR(0),2(R1)

これを知っている人は"化石決定"です。
0105デフォルトの名無しさんNGNG
TLCS-12A ってCPU 知ってる?
0106デフォルトの名無しさんNGNG
P6では、この>>86-87のソースが最適化みたいね。
これ以上はないでしょう。
0107#6411NGNG
>>99 ADVに使おうと思ってた。逆にアクション向けだったら
重いセル合成などやらない方針にしてたと思う。
ちなみに出力先サーフェスは16bit(ビット配置はさまざま)だった。
0108デフォルトの名無しさんNGNG
16bitでアルファブレンドしてるんだけど
640x480x16で20fpsも出てくれません。
全画面ブレンドして60fpsは無理でしょうか?
ブレンドも50%固定でなく、0〜100%でやってます。
CPUは400MHzです。
0109#6411NGNG
>>108 手で最適化してみたいのなら、下記から「最適化マニュアル」手繰ってちょ。
http://www.intel.co.jp/jp/developer/design/pentium/manuals/
アルファブレンドとかパッキングに関しては、下記から登録して、
Imageとかそのあたりを読み漁ってもらえれば。ただしぜんぶ英語。
http://developer.intel.com/software/idap/

漏れの経験では、P55C-266にて、640x480x16の
全画面クロスフェードが25fps超えてた。(DX5の時代)
当時のKlamath-266では、40fpsくらい逝ってた記憶も。
どうしても速くならなかったら、ソースの一部示せ。

なお、DirectDrawオンリーでなければ、最近のマシンでは60fps楽勝だ。
0110#6411NGNG
ageとこ。
ちなみに、当時のK6-2でもまともな速さで動いてたけど、
MMX器が1つしかないK6とかCyrix 686MXでは、トホホな感じだった。
VTuneでPentium最適化にしてしまったからのー。
0111デフォルトの名無しさんNGNG
>>106
やってる事が分かりやすいように、命令の順番を変えてませんし、
本当に早いか測ってませんが、ループの中身が、こんなのはどうですか?
P6のコストが、いまいち良く分からんので、自信はないけど、
P6に合わせて最適化すれば86のループよりは早くなりそうかと…。

(EBPはテーブル)
lopX:
mov eax, dwrod ptr [esi+000h]
mov ebx, dwrod ptr [edi+000h]
rol eax, 8
mov ecx, eax
mov edx, ebx
and eax, 000ff00ffh
and ebx, 0ff00ff00h
and ecx, 0ff00ff00h
and edx, 000ff00ffh
or ebx, eax
or ecx, edx
rol ebx, 8
movzx eax, cx
movzx edx, bx
shr ebx, 16
shr ecx, 16
mov al, byte ptr[ebp+eax]
mov bl, byte ptr[ebp+ebx]
mov cl, byte ptr[ebp+ecx]
mov dl, byte ptr[ebp+edx]
mov byte ptr[edi+000h], al
mov byte ptr[edi+001h], bl
mov byte ptr[edi+002h], cl
mov byte ptr[edi+003h], dl
add esi, 4
add edi, 4
dec nDivided_Width
jnz short lopX
0112デフォルトの名無しさんNGNG
>>106
うーん、ちょっと見た限りでは>>86-87もいいけど
>>79 も同じくらいの速さは出るようにに思うんだがなあ
 特にAthlonだと 79の勝ちのように思う
0113112NGNG
おお、>>111が Athlonではダントツの結果だね 79のさらに半分で計算出来る
さらに微妙な所を狙うなら後半のループの部分で
add はフラグが変化するから

LEA esi,[ esi+4]
mov al, byte ptr[ebp+eax]
mov bl, byte ptr[ebp+ebx]
mov cl, byte ptr[ebp+ecx]
mov dl, byte ptr[ebp+edx]
dec nDivided_Width
mov byte ptr[edi+000h], al
mov byte ptr[edi+001h], bl
mov byte ptr[edi+002h], cl
mov byte ptr[edi+003h], dl
LEA edi,[ edi+4]
jnz short lopX

と速めにJNZが使うフラグを確定させてやった方がいいかも
011464NGNG
>>113
decとjnzを離すとP6だとフラグストールしないか?
0115112NGNG
>>114
 この場合間に入れた演算命令がLEAだけだから
>依存関係を解消するために必要以上に離れていると
>前の命令の結果は現在の命令側のμop が必要とし
>た時点で、もはやディスパッチ・バッファに残っていない
>可能性がある。
 だけど
>基本的な目安は、依存関係が解消されるだけの時間を
>取りながらも、バッファから結果データが失われるほど長
>時間ではない程度
だから、 LEA1個くらいなら大丈夫なんでは?
011676NGNG
>>111 方針は >>76と似てるけど、レジスタを巧くばらけて使ってるから速いんだな

半分って事は 、1ピクセル3クロック程度?

27命令が 12クロックか・・・
0117デフォルトの名無しさんNGNG
>>113
Athlonだとそんなに>>111が速い?
うちのPentiumIIだと>>111より>>86の方が若干速いみたいよ。
0118112NGNG
>>117 そうだね。キャッシュをヒットさせる条件で2.5倍くらい差が出たよ
Athlonは整数演算もアドレス演算もパイプラインが3つあるから途中の
同種命令が固まってあっても苦にならないんだろうね

PenII/IIIは整数演算ユニットは2つで、シフトは片方でしか実行出来ない
から、 それ用に命令の順番を変更してみたらどうよ?
0119デフォルトの名無しさんNGNG
PenII/IIIは命令デコードの段階でパイプ詰まり起こしてます
0120デフォルトの名無しさんNGNG
>>118
Athlonだと1ピクセル当たり何クロックで処理できるの?
0121デフォルトの名無しさんNGNG
PenIIでの最適化ってどんなやつ?
2個ってことは、ペアリングとか?
0122111NGNG
とりあえず、出来る限りチェーンを断ち切りましたが、
後半部分が、上手く動かない可能性が高いので、
論理和、シフト、ゼロ拡張付きロード、「add esi, 4」、
「sub nDivided_Width, 001h」の位置を適当に入れ替えてみたり、
前回のように、1バイトずつストアする方法に戻してみたりして下さい。

(今回もEBPはテーブル)
lopX:
mov edx, dwrod ptr [esi+000h]
mov ecx, 000ff00ffh
mov ebx, 0ff00ff00h
mov eax, dwrod ptr [edi+000h]
and ecx, edx
and edx, ebx
and ebx, eax
shl ecx, 8
and eax, 000ff00ffh
shr ebx, 8
or ecx, eax
or edx, ebx
movzx eax, cx
shr ecx, 16
add edi, 4
movzx ecx, byte ptr[ebp+ecx]
movzx ebx, dx
shr edx, 16
movzx ebx, byte ptr[ebp+ebx]
shl ecx, 16
movzx edx, byte ptr[ebp+edx]
shl ebx, 8
movzx eax, byte ptr[ebp+eax]
shl edx, 24
or ebx, ecx
or edx, eax
add esi, 4
or edx, ebx
sub nDivided_Width, 001h
mov byte ptr[edi-004h], edx
jnz short lopX
0123112NGNG
>>122 コードが正しいとして、(dwrod は修正 byte ptrは取った)
Athlon で前回3.6クロック/ピクセルから 3.5クロック/ピクセルに改善されました
0124デフォルトの名無しさんNGNG
PentiumIIで計測してみたら
1次キャッシュに完全にヒットさせた状態で
>>86 が3.55クロック/ピクセル
>>122 が3.75クロック/ピクセル
くらい。

640×480ピクセル、ピクセルデータランダム、テーブルデータランダムだと、
>>86 が11.66クロック/ピクセル
>>122 が11.76クロック/ピクセル
くらいだった(ビデオメモリに転送せず、メインメモリ上で処理した場合)。
0125124NGNG
うちのPentiumIIでは次のような単純なコードが一番速かったよ。

mov edx, Width
lopX:
movzx ecx, byte ptr [esi]
shl ecx, 8
movzx eax, byte ptr [edi]
mov al, [tbl+eax+ecx]
mov [edi], al

movzx ecx, byte ptr [esi+1]
shl ecx, 8
movzx eax, byte ptr [edi+1]
mov al, [tbl+eax+ecx]
mov [edi+1], al

movzx ecx, byte ptr [esi+2]
shl ecx, 8
movzx eax, byte ptr [edi+2]
mov al, [tbl+eax+ecx]
mov [edi+2], al

movzx ecx, byte ptr [esi+3]
shl ecx, 8
movzx eax, byte ptr [edi+3]
mov al, [tbl+eax+ecx]
mov [edi+3], al

add esi, 4
add edi, 4

sub edx, 4
jne lopX
0126デフォルトの名無しさんNGNG
やっぱ、分岐も投機実行するからフラグの心配は意味なしだ
0127 NGNG
Winでマシン語プログラミングなんかできるのか?
「EXEファイルはOSは理解するがCPUは理解しない」
APIでしか交信できない
.dll
.h
.lib
.drv
.VxD
.sys
.ocx
0128デフォルトの名無しさんNGNG
>>127
さぁ、どうなんだろうね?難しい質問だね。
答えが分かったら是非教えてね。
0129#6411NGNG
>>128 禿げしく同意。難しい日本語の質問だね。
0130111NGNG
>>123
どこかミスってましたか?(^^;;;
確認してなかったので、申し訳ないです。m(_ _)m
と言う訳で、またまた確認してませんが、P6用に修正しました。
マニュアルしか読んでないので、本当に早いのか疑問はありますが…。

ループの外は何も考えてないので、適当に、その外に吸収してやって下さい。

(またまたEBPがテーブル)

mov edx, 0ff00ff00h
and edx, dwrod ptr [ edi+000h ]
mov ebx, 0ff00ff00h
and ebx, dword ptr [ esi+000h ]
shr edx, 8
mov eax, 000ff00ffh
or edx, ebx
sub nDivided_Width, 1
jz short lopX_END

lopX:
and eax, dwrod ptr [ esi+000h ]
mov ecx, 000ff00ffh
add esi, 004h
and ecx, dwrod ptr [ edi+000h ]
movzx ebx, dx
shl eax, 8
movzx ebx, byte ptr [ ebp+ebx ]
shr edx, 16
or ecx, eax
movzx edx, byte ptr [ ebp+edx ]
movzx eax, ecx
shl ebx, 8
movzx eax, byte ptr [ ebp+eax ]
shr ecx, 16
shl edx, 24
movzx ecx, byte ptr [ ebp+ecx ]
or eax, edx
add edi, 004h
shl ecx, 16
mov edx, 0ff00ff00h
or eax, ebx
and edx, dwrod ptr [ edi+000h ]
mov ebx, 0ff00ff00h
or ecx, eax
and ebx, dword ptr [ esi+000h ]
shr edx, 8
mov eax, 000ff00ffh
mov dwrod ptr [ edi-004h ], ecx
or edx, ebx
sub nDivided_Width, 1
jnz short lopX
0131111NGNG
(続き)

lopX_END:
and eax, dwrod ptr [ esi+000h ]
mov ecx, 000ff00ffh
and ecx, dwrod ptr [ edi+000h ]
movzx ebx, dx
shl eax, 8
movzx ebx, byte ptr [ ebp+ebx ]
shr edx, 16
or ecx, eax
movzx edx, byte ptr [ ebp+edx ]
movzx eax, ecx
shl ebx, 8
movzx eax, byte ptr [ ebp+eax ]
shr ecx, 16
shl edx, 24
movzx ecx, byte ptr [ ebp+ecx ]
or eax, edx
shl ecx, 16
or eax, ebx
or ecx, eax
mov dwrod ptr [ edi+000h ], ecx
0132デフォルトの名無しさんNGNG
>>127
全角アルファベットあたりがかなり難解。
013364NGNG
sagaって来たね(藁
そろそろ終了か!?
0134124NGNG
PentiumIIでは>>122より>>86が若干速いみたいに書いたけど、
コードのアライメントによって微妙に変わってくるね。当たり前だけど。
PentiumIIではほとんど同じ速度みたい。
>>130も>>122や>>86より速いということはなかった。
0135デフォルトの名無しさんNGNG
JMP _NATUYASUMI;
0136デフォルトの名無しさんNGNG
>>127
マジで言ってるのかなー?
CPUはマシン語以外理解できないと思うんだけど。
0137デフォルトの名無しさんNGNG
hage
0138デフォルトの名無しさんNGNG
sage
0139デフォルトの名無しさんNGNG
もうネタないかな?
0140デフォルトの名無しさんNGNG
だれかアセンブラで高級言語作って!
■ このスレッドは過去ログ倉庫に格納されています