掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
Delphiで人工ニューラルネットワーク(Artificial Neural Network)のクラスを作りましたが遅いです (ID:150813)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
TVec4を間に入れる必要は無いでしょう。 まずWin64なら少なくともメモリー確保時に 16byteアラインはされていると思います。それであれば遅くはなっても動くような記述があったような。 そして、それでもパフォーマンスが半減するだけで並列に8個計算できるのですから現状の何倍もの速度は出るはずです。 32byteアラインされているかどうかは、 https://urame.sakura.ne.jp/w/wiki.cgi/lazarus?page=Lazarus%A4%C7x64+SIMD%CC%BF%CE%E1%A4%F2%BB%C8%A4%C3%A4%C6%A4%DF%A4%EB でやってるように if (integer(pD) and (32 - 1)) <> 0 then 32byteアラインされてないよ と確認出来ます(ポインタの下位5bitが0ならアラインされているわけです) 16byteアラインされているかどうかは、このコードで32を16にしてやれば良いわけです アラインされていなければ、SIMD部をスキップして while Count > 0 do begin pD^ := pD^ + MulData[0] * pS^; Inc(pD); Inc(pS); Dec(Count, 32); end; だけを実行させれば良いでしょうし、この部分だけでもWIN64だと movss -0x40(%rbp),%xmm0 mulss (%rax),%xmm0 addss (%rdx),%xmm0 mov -0x48(%rbp),%rax movss %xmm0,(%rax) のようにx87FPUではなく SSE命令を使っていますから これを4word並列変更するだけで高速化は出来るのでしょう。 Delphiが32bit版ならごめんなさい。 で、Delphiが64だけど アセンブラが対応してない場合は Lazarus64等のコンパイル出来る環境でコンパイルして そこから命令を直接 DBで書いてゆけばいけます。 例えば VFMADD231PS YMM0, YMM5, [RAX] なら 000000010002F87C c4e255b800 vfmadd231ps (%rax),%ymm5,%ymm0 から最初は64bitアドレス、命令バイトの並びですから c4e255b800 の部分から DB c4h,e2h,55h,b8h,00h のように書いてやればOK なおアセンブラでの16進数は c4hではなく 0c4hであったり 0xC4 だったりでDelphiがどうかは判りません 一度 ブレークポイントをかけてCPU窓を見て判断して下さい 以下、該当部分のLazarus-アセンブラ窓(逆アセ表示はlinuxスタイルなので転送方向が逆です) while Count >= 32 do 000000010002F850 eb68 jmp 0x10002f8ba <AVXCOFFSUM+314> 000000010002F852 660f1f440000 nopw 0x0(%rax,%rax,1) LEA RCX, MulData[0]; 000000010002F858 488d4dc0 lea -0x40(%rbp),%rcx VBROADCASTSS ymm5, [RCX] //AVX 256bitレジスタに32bit値を埋める 000000010002F85C c4e27d1829 vbroadcastss (%rcx),%ymm5 MOV RAX, pS // ソースアドレスをRAXに 000000010002F861 488b45b0 mov -0x50(%rbp),%rax MOV RDX, pD //加算してゆく先 000000010002F865 488b55b8 mov -0x48(%rbp),%rdx VMOVUPS YMM0, [RDX] //AVX 000000010002F869 c5fc1002 vmovups (%rdx),%ymm0 VMOVUPS YMM1, [RDX+32] 000000010002F86D c5fc104a20 vmovups 0x20(%rdx),%ymm1 VMOVUPS YMM2, [RDX+64] 000000010002F872 c5fc105240 vmovups 0x40(%rdx),%ymm2 VMOVUPS YMM3, [RDX+96] 000000010002F877 c5fc105a60 vmovups 0x60(%rdx),%ymm3 VFMADD231PS YMM0, YMM5, [RAX] //FMA YMM0+=YMM5*[RAX] 000000010002F87C c4e255b800 vfmadd231ps (%rax),%ymm5,%ymm0 VFMADD231PS YMM1, YMM5, [RAX+32] 000000010002F881 c4e255b84820 vfmadd231ps 0x20(%rax),%ymm5,%ymm1 VFMADD231PS YMM2, YMM5, [RAX+64] 000000010002F887 c4e255b85040 vfmadd231ps 0x40(%rax),%ymm5,%ymm2 VFMADD231PS YMM3, YMM5, [RAX+96] 000000010002F88D c4e255b85860 vfmadd231ps 0x60(%rax),%ymm5,%ymm3 VMOVUPS [RDX], ymm0 000000010002F893 c5fc1102 vmovups %ymm0,(%rdx) VMOVUPS [RDX+32], ymm1 000000010002F897 c5fc114a20 vmovups %ymm1,0x20(%rdx) VMOVUPS [RDX+64], ymm2 000000010002F89C c5fc115240 vmovups %ymm2,0x40(%rdx) VMOVUPS [RDX+96], ymm3 000000010002F8A1 c5fc115a60 vmovups %ymm3,0x60(%rdx) Inc(pD, 32); 000000010002F8A6 488145b880000000 addq $0x80,-0x48(%rbp) Inc(pS, 32); 000000010002F8AE 488145b080000000 addq $0x80,-0x50(%rbp) Dec(Count, 32); 000000010002F8B6 836de020 subl $0x20,-0x20(%rbp) while Count >= 32 do 000000010002F8BA 837de020 cmpl $0x20,-0x20(%rbp) 000000010002F8BE 7d98 jge 0x10002f858 <AVXCOFFSUM+216> while Count > 0 do
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.