トリッキーなコード その2
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNG大体トリッキーなコードを書く奴に限って
致命的なバグを出したりするんだけど、
書きたいもんはしょうがない。
・・・らしい
前スレ http://pc3.2ch.net/test/read.cgi/tech/983191866
0153デフォルトの名無しさん
NGNG151を良く見ろ、コードが全く違うぞ。
それ以前の問題だ。
0154107
NGNGまあ、時間測るだけだからいいか
0155デフォルトの名無しさん
NGNGfor や func call やタスクスイッチのオーバーヘッドの方が
大きかったりしないか?
>>129 の方がまだ信憑性ありそうだな。
お前ら >>129 のコード実行してOS、CPU(ステップ&周波数含む)と共に報告スレ。
漏れはスペースが全部なくなってて挫折しますた。(w
0156デフォルトの名無しさん
NGNGpush/pop での交換は確実に遅い。スタック操作を伴なうから
プロテクトモードでならメモリ保護チェックが必ず発生してしまう。
#コンパイラの最適化レベルを上げるとcall/retを減らすように
#アセンブルコードを出力しようとするのもこの理由による。
xor他による交換の場合は、二つ目、三つ目の演算命令は
その前の演算命令によってレジスタ内容が完全確定していないと
演算自体することが出来ないわけだから、それぞれの命令間で
パイプラインストールが発生する可能性が非常に高い。
#それぞれの命令間にNOPを挟んでも実行時間に大差なければほぼ間違いない
xchg の場合、厳密にはレジスタの内容を交換しているのではなくて、
現在ではレジスタの名前のほうを(CPU内部的に)交換していると思っていい。
なので交換対象レジスタの組み合わせによってはストールしにくい(またはしない)
#むかしのCPUでは確かにレジスタ内容自体を交換していた。(RISC系は現在でもそう)
#けど多段パイプラインやコード予測機能の絡みもあるので、
#CISC系ではそういうのに影響を与えにくい設計に進化してきている(はず)
まあ、純粋培養のソフト屋さんにハード依存の話をしても、
なかなか想像力が付いて来ないだろうとは思うけどね…。
0157デフォルトの名無しさん
NGNGマジレスカコワルイ
push/popはメモリアクセスする時点で遅いのは確定。
俺の興味はどっちかというとどれ位遅いかだな。
xorやmovによる交換も実質レジスタリネーミングされると
考えればパイプラインストールはほぼ発生してないはず。
129の結果どおりだとすれば、156のとは正反対の
mov/xor 3回よりは xchg の方が早いが、
xchg単体は mov/xor単体よりもずっと遅い
という結果が出てくる。
0158デフォルトの名無しさん
NGNGここの住民はそのうちメモリ容量とかHDD容量とかビデオチップとか
言い出す予感。
0159デフォルトの名無しさん
NGNG0160107
NGNG負荷を測るなら for や call の時間込みで測定するのがホントじゃないの?
まあ、ループした方がいいっていうなら
procedure TForm1.Button1Click(Sender: TObject);
procedure SwapXCHG;
var i:Integer;
begin for i:=0 to 100-1 do asm xchg eax, edx end;
end;
procedure SwapXOR;
var i:Integer;
begin for i:=0 to 100-1 do asm
xor eax, edx
xor edx, eax
xor eax, edx
end;
end;
function RDTSC:Integer;
asm RDTSC
end;
var cXCHG,cXOR,c0,c1,i,j:Integer;
var a,b:Integer;
begin
a:=1; b:=2; cXCHG:=0;cXOR:=0;
c0:=RDTSC;
for j:=0 to 9 do begin
SwapXCHG; c1:=RDTSC;inc(cXCHG,c1-c0);c0:=c1;
SwapXOR; c1:=RDTSC;inc(cXOR,c1-c0);c0:=c1;
end;
Memo1.Lines.Add(Format('XOR=%5d XCHG=%5d',[cXOR,cXCHG]));
end;
これでも 結果は XOR= 3589 XCHG= 3631 でAthronでは同じって結論でいいんじゃないの
0161107
NGNGXOR= 4044 XCHG= 3756
って事で、若干 XCHG 命令が速いね。
まあ当然の結果だけど。
0162107
NGNGabs(x) を CDQ /XOR /SUB で書けるように
max(a,b) を書くのに分岐無しで書くのに応用出来る
0163デフォルトの名無しさん
NGNG何を言っているのかわからないんだけど・・・。
> xorやmovによる交換も実質レジスタリネーミングされると
> 考えればパイプラインストールはほぼ発生してないはず。
そうなの??
mov はわからんでもないけど、xor が?
> xchg単体は mov/xor単体よりもずっと遅い
> という結果が出てくる。
単体で比較して何か意味あるの?
mov や xor に xchg 相当の事をやらせて初めて比較の意味があるんだけど。
0164デフォルトの名無しさん
NGNGアセンブラの話よりも、本格的にトリッキーなコードキボンヌ
0165デフォルトの名無しさん
NGNG0166デフォルトの名無しさん
NGNGprintf("VOYAGER マンセー\n");
return 0;
}
0167デフォルトの名無しさん
NGNGシフトJISの1バイト目か判定(コピペ
外出だったらスマソ。
新年もトリッキーなコードが飛び交いますよう
0168デフォルトの名無しさん
NGNG0x05, 0x0000ffff ;add eax, 0000ffff
}
機械語直打ちキター
0169デフォルトの名無しさん
NGNG大晦日に萎えるソースコード持ってくるな・・・
前スレ嫁、そして初日の出を見ることなく氏ね
0170デフォルトの名無しさん
NGNG0xff, 0xf1 ;push ecx
0xe8, 0x40229833 ;call 40229833
}
(´∀`)あはは
0171デフォルトの名無しさん
NGNG0x90
}
( ゚∀゚ )あっひゃっひゃっひゃ
0172デフォルトの名無しさん
NGNGそれは前スレで外出だったと思う。
どこからのコピペ?
0173デフォルトの名無しさん
NGNGhttp://www.st.rim.or.jp/~phinloda/phin/phin9509.html
0174デフォルトの名無しさん
NGNGNIFTYのどこかだと思ってたけど、元はFCだったか。
0175デフォルトの名無しさん
NGNGマシン語の世界ではごくごく普通に使ってた計算式であり、
アルゴリズムなんだけど、高級言語に浸かってくると
やっぱり忘れてしまうわな、そういうの…。
#CMP一発で5分岐するとかって、あったなぁ。
0176ツッコミ初め
NGNG別にマシン語の世界じゃなくたって、一般的では。
境界線は自前で書いてるか、ライブラリ使ってるか、じゃないの?
0177デフォルトの名無しさん
NGNG大小によって -1,0,1を返す関数
type TValueSign = -1..1;
function CompSign(A,B:Integer):TValueSign;
asm
CMP EAX,EDX; //A-B
SETGE CL
ADD CL,CL
DEC CL
CMP EAX,EDX; //A-B
SETZ AL
DEC AL
AND AL,CL
CBW
CWDE
end;
0178デフォルトの名無しさん
NGNG0179デフォルトの名無しさん
NGNGvoid SwapXCHG(int& a, int& b)
{
asm {
mov eax, [a]
mov ebx, [b]
xchg eax, ebx
mov [a], eax
mov [b], ebx
}
}
void SwapXOR(int& a, int& b)
{
asm {
mov eax, [a]
mov ebx, [b]
xor eax, ebx
xor ebx, eax
xor eax, ebx
mov [a], eax
mov [b], ebx
}
}
0180デフォルトの名無しさん
NGNG{
int i;
asm {
RDTSC
mov [i], eax
}
return i;
}
int main()
{
int a = 1, b = 2;
int c0, c1, cXCHG = 0, cXOR = 0;
for (int j = 0; j < 10; j++) {
c0 = RDTSC();
for (int i = 0; i < 1000; i++) SwapXCHG(a, b);
c1 = RDTSC();
cXCHG += c1 - c0;
c0 = RDTSC();
for (int i = 0; i < 1000; i++) SwapXOR(a, b);
c1 = RDTSC();
cXOR += c1 - c0;
}
std::cout << "XCHG = " << cXCHG << std::endl;
std::cout << "XOR = " << cXOR << std::endl;
}
0181デフォルトの名無しさん
NGNG両者の関数のクロック数にほとんど差がない。
>>177の比較関数もC++化して実行してみたが、単純なif文の方が約40%ほど
速かった。アセンブラによるトリッキーな書き方にはクロックの上でのアドバン
テージはないのだろうか。
0182デフォルトの名無しさん
NGNG比較の場合はランダムデータですか?
最近のCPUは分岐予測が余程優れているのかな…。
0183デフォルトの名無しさん
NGNGランダムデータではないです。変数に値を入れておいて比較しました。
こんな感じ。
int main()
{
int c0, c1, cSETCC = 0, cIF = 0;
int a = 1, b = 2;
for (int j = 0; j < 10; j++) {
c0 = RDTSC();
for (int i = 0; i < 1000; i++) {
cmp1(a, b);
cmp1(b, a);
cmp1(a, a);
}
c1 = RDTSC();
cSETCC += c1 - c0;
c0 = RDTSC();
for (int i = 0; i < 1000; i++) {
cmp2(a, b);
cmp2(b, a);
cmp2(a, a);
}
c1 = RDTSC();
cIF += c1 - c0;
}
std::cout << "setcc = " << cSETCC << std::endl;
std::cout << "if = " << cIF << std::endl;
}
0184デフォルトの名無しさん
NGNG分岐予測が働きにくくなるからでしょうね。
0185デフォルトの名無しさん
NGNGどれらいのランダムネス(?)が境界になるのか知りたいところ
0186デフォルトの名無しさん
NGNGP4だと、40個毎に乱数の系列を戻した時にほぼ同じタイムになるみたい。
const int N = 1000;
int cmp1(int& a, int& b)
{
int i;
asm {
MOV EAX,[a]
MOV EBX,[b]
CMP EAX,EBX; //A-B
SETGE CL
ADD CL,CL
DEC CL
CMP EAX,EBX; //A-B
SETZ AL
DEC AL
AND AL,CL
CBW
CWDE
MOV [i],EAX
}
return i;
}
int cmp2(int& a, int& b)
{
if (a < b) return -1;
else if (a > b) return 1;
return 0;
}
0187デフォルトの名無しさん
NGNG{
int i;
asm {
RDTSC
mov [i], eax
}
return i;
}
int main()
{
int c0, c1, cSETCC = 0, cIF = 0;
int a[N], b[N];
for (int i = 0; i < N; i++) {
a[i] = std::rand(); // ここで比較用データをセットする
b[i] = std::rand(); //
if (i % 40 == 0) std::srand(0); // 乱数系列初期化用
}
0188デフォルトの名無しさん
NGNGc0 = RDTSC();
for (int i = 0; i < 1000; i++) cmp1(a[i], b[i]);
c1 = RDTSC();
cSETCC += c1 - c0;
c0 = RDTSC();
for (int i = 0; i < 1000; i++) cmp2(a[i], b[i]);
c1 = RDTSC();
cIF += c1 - c0;
}
std::cout << "setcc = " << cSETCC << std::endl;
std::cout << "if = " << cIF << std::endl;
}
長文スマソ
0189デフォルトの名無しさん
NGNG少し前まで、分岐予測ミスのペナルティは大きくて 分岐なしが平均的には余程速かったのになあ
0190デフォルトの名無しさん
NGNGしかしこの比率ってCPUの世代で変わったりするのかな・・・
0191デフォルトの名無しさん
NGNG分岐履歴バッファがCPU内部にはあって、何重もの入れ子になった
ループの分岐を予測できるらしいですね。
P4のような深いパイプラインを持つCPUでは不可欠の機構なので
相当念入りに作ってあるようです。
P3やAthlonの結果も知りたいのですが、どなたか試してみていただ
けませんか?
0192デフォルトの名無しさん
NGNG概ねcmp1のほうが速いですが、評価順や最適化の有り無しでも
結果が変わるようです。(i % 40)の部分はほぼ影響なかった。
正確に測るには関数内に_asmでRDTSC入れてDWORD境界の
対策をしないと駄目かも知れず。
あ、最適化するとcmp2(if 〜 else if 〜)の関数内にあるジャンプ
命令は1個ですたw
0193デフォルトの名無しさん
NGNG0194デフォルトの名無しさん
NGNGこんな小さなコードだと少しはロスがあると思うわけ。
(フルアセンブラや、gccやbccのようにレジスタを直接返せれば別だけど)
ってゆーかさ、"トリッキーなコード"を名乗るんだったら、
せめてこの程度までは最適化してから比較しようよ。
と言ったものの、あまり詳しくないんで、
見た目が最適化されただけで、内部的なクロック数は増えてるしれない。
int cmp1(int a, int b)
{
asm {
mov eax, a // 引数をレジスタ渡しだと・・・
cmp eax, b //
setl al
setg cl
neg al
xor al, cl
cbw
cwde
mov a, eax // <-これがじゃま
}
return a;
}
0195デフォルトの名無しさん
NGNGSETxx はフラグに影響を与えなかったっけ?
0196デフォルトの名無しさん
NGNGコンパイラはフラグを「比較直後」以外に使うのがうまくないんだよね。
その後で並べ替えることはあっても。
だから、アセンブラレベルでなら、add/subの代わりにleaを用いてフラグを維持し、
それから条件を調べる(jmp等)って方法なんかもでてくるわけさ。
もちろん、よほどクリティカルな部分でない限り、意味は無いけどね。
よく考えたら、>>194はxorではなくorを使ってもいいんだけど、
xorの方が意味が分かりにくい==トリッキーってことで許して。
で、ほぼ同じロジックでCで書くとしたら
int cmp2(int a, int b)
{
return (a < b) | -(a > b);
}
だね。
0197デフォルトの名無しさん
NGNG持ってた本に実行後にフラグが変更されてるような用例載ってたから勘違いしてた。
じゃあ1ステップ短く出来るよ
type TValueSign = -1..1;
function CompSign(A,B:Integer):TValueSign;
asm
CMP EAX,EDX; //A-B
SETLE AH
SETGE AL
SUB AL,AH
CBW
CWDE
end;
0198デフォルトの名無しさん
NGNG194から急に厨臭くなった・・・
0199デフォルトの名無しさん
NGNGと>>197を読んで思い出したけど、
似たようなロジックは半年くらい前にC言語スレで見た(書いた)気がする。
減算結果の最上位bitをシフトしてxorとるやつ。
とここまで書いて、その時見たのは「aとbの符号が一致しているかを返す」
だったのを思い出した。
そういうのがあったからxor使っちゃったんだな(もちろん、subの方が良いけど)
0200デフォルトの名無しさん
NGNGん?ベンチマーク続けてかまわないんじゃないの?
一つのスレッドで複数の話題が進行するなんてよくあることだし。
要は、分岐予測があたることに期待した単純なコードと
分岐予測がはずれる可能性に備えて少し複雑なコードで
CPUやデータのばらつきによって、どちらが良いか、どのあたりが分岐点になるのかでしょ?
実際、現在のCPUでは分岐予測ミスやメモリアクセスなどの
ペナルティを減らす方がはるかに重要だし。
0201デフォルトの名無しさん
NGNGそういうのが当てにならないにもかかわらず
アナクロな方向になってあきれただけ
0202デフォルトの名無しさん
NGNG・メモリアクセスがない
・分岐がない
・複雑な命令がない
・依存関係のある命令が少ない
場合ならば、充分意味があるよ。
少なくとも俺は、
「両方Cで書いて分岐の有無によるテスト」か
「両方アセンブラで書いて分岐の有無によるテスト」
にしないなら、
「片方をC、片方をアセンブラで書いてどちらも分岐命令を使う」
「片方をC、片方をアセンブラで書いてどちらも分岐命令を使わない」
でなければ、あまり意味はないと思っているけどね。
出来れば、全てアセンブラでアラインも揃え、
分岐の有無による差を見たいけどね。
0203デフォルトの名無しさん
NGNG単なる思い込みコードをベンチマーク結果なしにみせつけられてもねえ。
0204デフォルトの名無しさん
NGNGこのスレに書く"トリッキーなコード"はベンチマークがなきゃ意味無いよね。
0205デフォルトの名無しさん
NGNGコード量削減のためならバイト数の計測。
他人を驚かすのが目的なら・・・どうしよう
0206デフォルトの名無しさん
NGNGあ! 忘れてた。 MOVSX があったんだ。
そりゃMOVSX1命令の方が短いでしょ
type TValueSign = -1..1;
function CompSign(A,B:Integer):TValueSign;
asm
CMP EAX,EDX; //A-B
SETLE AH
SETGE AL
SUB AL,AH
MOVSX AX,AL
end;
0207デフォルトの名無しさん
NGNGベンチマーク取りましたよ。
test1が>>183の外ループを10倍したもの
test2が>>187-188の外ループを10倍したもの
cmp1が>>197の前後にロードとストアを入れたもの
cmp2が>>186のcmp1の引数を参照にしなかったもの
呼び出し規約はcdeclで。
test1
cmp1 = 4943201
cmp2 = 7133229
test2
cmp1 = 1677185
cmp2 = 2230045
ま、こんなもんでしょ。
ロード/ストア/スタックフレーム操作/callが入るからそうそう極端な差はつかないね。
0208207
NGNG0209デフォルトの名無しさん
NGNG0210デフォルトの名無しさん
NGNG「明らか」な結果をわざわざ測定するのは今回だけ。学生実験とは違うから。
まあ雪で出かけられない中、良い暇つぶしになったよ。
0211デフォルトの名無しさん
NGNGんなアホな
0212デフォルトの名無しさん
NGNGもちろん、何十年後かのアーキテクチャでもそうだとは言い切らないけど、
今後10年の間は明らか。
逆転するようなことがあっても、その時代にはx86(IA-32)は寿命を終えている。
0213デフォルトの名無しさん
NGNG0214デフォルトの名無しさん
NGNG残念。
0215デフォルトの名無しさん
NGNG0216デフォルトの名無しさん
NGNG煽りにも精一杯反応しちゃうよ。
ねー、ぼくちゃんは厨房じゃないんでしょ?
煽りに反応しちゃだめでしょ。
0217デフォルトの名無しさん
NGNG0218デフォルトの名無しさん
NGNG単なる指摘でしょう。
そういやIA-32って今年で18周年だね。
0219デフォルトの名無しさん
NGNG0220デフォルトの名無しさん
NGNG0221デフォルトの名無しさん
NGNG有意義な時間を過ごせました
0222デフォルトの名無しさん
NGNG俺が>>202の後半で指摘した「ベンチマークは測定条件を揃えて」ってのは
放置しちゃったのかな?
>>198で、すごくベンチマークが楽しみそうだったのに。
0223デフォルトの名無しさん
NGNG>>188まででわかったんだから
AthlonもP3も関係ないし、どちらが何%速いとか
どこで逆転するとかの報告は必要ないな。
確かに、アセンブラの方を最適化したから厨房臭かったかもね。
むしろ、「これ↓の結果を比較しろ」と書いた方が良かったか?
int cmp1(int a, int b) {
return (a > b) - (a < b);
}
int cmp2(int a, int b){
if (a < b) return -1;
else if (a > b) return 1;
return 0;
}
最後に付け加えとこ。
>>177(以降)はSETccを使って分岐をなくしているけど、
CMOVでも同じ結果が出てる。
少なくとも、現存のx86アーキテクチャは
分岐予測成功 > CMOV >>> 分岐予測失敗
になってる。
0224デフォルトの名無しさん
NGNG> 分岐予測成功 > CMOV >>> 分岐予測失敗
>になってる。
P3からP4になって、さらに強まった気がするんだけどどうかなあ
0225デフォルトの名無しさん
NGNGがんばれ!
0226デフォルトの名無しさん
NGNG0227デフォルトの名無しさん
NGNGステップ数が少ないので、if文では完全な規則性のある数を比較した場合
以外ほとんどかなわない。
CMOVを使ったプログラムでも検証してみます。
0228デフォルトの名無しさん
NGNGをロードできると思ってたけど、だめなのね。
int cmp1(int& a, int& b)
{
static int one = 1, mone = -1;
int i;
asm {
MOV ESI,a
MOV EDI,b
MOV EAX,0
CMP ESI,EDI;
CMOVL EAX,mone
CMOVG EAX,one
MOV i,EAX
}
return i;
}
0229デフォルトの名無しさん
NGNGCMP じゃなlくて SUB にすれば 引算結果のゼロを使えるから1ステップ短くなるよ
0230デフォルトの名無しさん
NGNGMOV ESI,a
MOV EDI,b
int&a, int& bとなっているので、aとbはポインタを与えてしまう。だからこれは
MOV ESI,a
MOV ESI,[ESI]
MOV EDI,b
MOV EDI,[EDI]
と書かなければならない。このような不都合を避けるため、intの参照ではなく
値で渡す事にした。if文の方も値で渡すようにしたのだが、意外とif文が速くなっ
た。乱数の発生系列の初期化を70個毎にしないとCMOVccやSETccが負けて
しまう。
0231デフォルトの名無しさん
NGNGそれはなかなかトリッキーですね!早速やってみます!
0232デフォルトの名無しさん
NGNGこのようにしてみました。規則的なifの速度にはかなわないけど、不規則な
ifに対しては、乱数の初期化を10個毎にしても勝てます!(Pentium4)
asm {
MOV EAX,a
MOV EBX,b
SUB EAX,EBX;
CMOVL EAX,mone
CMOVG EAX,one
MOV i,EAX
}
0233デフォルトの名無しさん
NGNG分岐なしに書けるなら、多少冗長に見えても、使った方が全体のパフォーマンスが上がる事がおおいよ。
年々大きくはなっても、分岐ターゲット・バッファ(BTB)はやっぱり有限だからさ。
0234デフォルトの名無しさん
NGNG大規模なプログラムだと、分岐の過程は一般的にランダムだから、分岐フロー
を無くすようなプログラムが効果的でしょうね。ただ、短いコードでないと、分岐
無しで動作するようなプログラムを書く事は非常に難しいでしょうけど。
0235デフォルトの名無しさん
NGNGいやそうじゃなくて、再利用度の高い一部の関数とかを分岐無しが可能なら、出来る時に書いておけば
全体のパフォーマンスが上がるだろうって事。
たとえ、その関数だけ評価して if 文よりパフォーマンスが悪くても、
もちろん重い処理の内側のループを書くような場合は別だけどさ
0236デフォルトの名無しさん
NGNGああなるほど、BTBをなるべく消費しない関数が書けるなら書いておこうって
事ですね。納得。その分別の箇所でBTBが有効活用できるって事か。
0237デフォルトの名無しさん
NGNG0238デフォルトの名無しさん
NGNG0239デフォルトの名無しさん
NGNG0240デフォルトの名無しさん
NGNGキャッシュにヒットしないと遅い予感
って、そんな場合は、ほとんど意味が無いから置いといて
Pen4はCMOVccのレイテンシがマニュアルに見当たらないので
知らなかったけど結構早かったんですね…
でも、おそらくP6系ではSETccの方が早いはずので
P6系を持ってる方はレッツチャレンジ♪
(と言っても、あまり差は出ないと思うけど…)
ついでに両方の値をレジスタに入れる必要は…
asm {
MOV EAX,a
SUB EAX,b
CMOVL EAX,mone
:
}
0241デフォルトの名無しさん
NGNGSEにプログラム作らせる事自体がトリッキー
0242デフォルトの名無しさん
NGNG年齢もしりたいw
0243デフォルトの名無しさん
NGNG2年間、もってくれるかなと思ってたけど、
それまでに落ちちゃうかなぁ。
0244IP記録実験
NGNGhttp://qb.2ch.net/test/read.cgi/accuse/1042013605/
1 名前:ひろゆき ◆3SHRUNYAXA @どうやら管理人 ★ 投稿日:03/01/08 17:13 ID:???
そんなわけで、qbサーバでIPの記録実験をはじめましたー。
27 名前:心得をよく読みましょう 投稿日:03/01/08 17:20 ID:yL/kYdMc
SETTING.TXT管轄でないということは全鯖導入を視野に、か?
38 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:22 ID:rLfxQ17l
>>27
鋭いです。
73 名前:ひろゆき ◆3SHRUNYAXA 投稿日:03/01/08 17:27 ID:rLfxQ17l
>ところで、IPが抜かれて何か今までと変わることってあるのでしょうか?
・今までより、サーバが重くなる。
・裁判所や警察からの照会があった場合にはIPを提出することがある。
0245デフォルトの名無しさん
NGNG0246デフォルトの名無しさん
NGNG0247デフォルトの名無しさん
NGNG>>10
0248デフォルトの名無しさん
NGNGllllllllllll lllll
lllllll lllll
lllll llllll
lllll llllllllll llllllllll lllll
lllll lllll llllllllll lllllllllllllllllllllllllllllllllll lllllll
lllll llllllllll llllllllll lllllllllllllll lllll
llllllllll llllllllll llllllllll lllll lllll lllllllll
llllllllll lllll llllllll
∧_∧ ∧_∧ ∧_∧ ∧_∧
( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`)
∧_∧ ) ∧_∧ )∧_∧ )∧_∧ )
( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`)
∧_∧ ) ∧_∧ ) ∧_∧ )∧_∧ )
( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`) ( ´_ゝ`)/|
(____) (____) (____) (____)
/ ./|./ /|./ /|/ /|
| ̄ ̄ ̄|/| ̄ ̄ ̄|/| ̄ ̄ ̄|/| ̄ ̄ ̄|/|
|| ̄ ̄ ̄|| || ̄ ̄ ̄|| || ̄ ̄ ̄|| || ̄ ̄ ̄||
0249デフォルトの名無しさん
NGNG0250デフォルトの名無しさん
NGNGひろしま必死だなっと・・・
0251デフォルトの名無しさん
NGNG0252デフォルトの名無しさん
NGNG■ このスレッドは過去ログ倉庫に格納されています