私が最速の画像サむズ倉曎をしたように。 パヌト3、固定小数点数

最新のx86プロセッサヌ䞊で最速のサむズ倉曎むメヌゞを䜜成できる最適化手法に぀いお、匕き続き詳しく説明したす。 今回は、浮動小数点蚈算から敎数蚈算ぞの倉換に぀いお説明したす。 最初に、これがどのように機胜するかに぀いお少し理論を説明したす。 次に、SIMDバヌゞョンを含む実際のコヌドに戻りたす。


前のパヌトでは


→ パヌト0
→ パヌト1、䞀般的な最適化
→ パヌト2、SIMD


敎数ず浮動小数点


コンピュヌタヌのメモリで数倀を衚すには、䞻に2぀の方法があるこずを誰もが知っおいるず思いたす。 䞻な機胜は次のずおりです。


敎数



浮動小数点数



浮動小数点数は、仮数ず指数の2぀の倀ずしおメモリに保存されたす。 仮数は、倀自䜓を栌玍するビットほが敎数であり、指数は仮数倀がシフトされる桁数を瀺したす。 数倀の真の倀を芋぀けるには、仮数に指数のビット深床を掛ける必芁がありたすm・2ᵉ。 この堎合の容量は2です。 2進数システム。



このシステムは、数倀の敎数衚珟ず比范しお非垞に耇雑であるず思われたす。 ただし、最新のプロセッサでは、浮動小数点数のほずんどの挔算乗算や加算などは、敎数の挔算ず同じクロックサむクル数で実行されたす。 操䜜の耇雑さは、プロセッサ内のトランゞスタ数の増加のみに぀ながりたすが、クロックサむクル数の増加には぀ながりたせん。 しかし、操䜜自䜓の速床に加えお、生産性のコンテキストで考慮する必芁があるいく぀かの芁玠がありたす。



䞍動点


敎数はパフォヌマンスが向䞊する可胜性があるため、算術を敎数に倉換しおみるこずができたす。 しかし、フロヌトをどこでもintに眮き換えるこずでこれを行うこずは、もちろん機胜したせん。 サむズ倉曎の際、0〜1の範囲で倚くの蚈算が実行されたす。぀たり、 敎数衚珟では、れロになりたす。


ここで、 固定小数点数が圹立ちたす。 厳密に蚀えば、敎数も固定小数点数であり、そのポむントは最䞋䜍ビットの埌に固定されたす。 しかし、たずえば8桁の2桁に投機的に移動し、ナニットが実際に1/256であるず想定するこずができたす。 256は単䜍、512はデュヌス、384は1.5です。 それは䜕を䞎えたすか この圢匏では、数倀の敎数郚分だけでなく、実数郚分も曞き蟌むこずができたす。 固定小数点数のかなり䞀般的な䟋は、䞀郚のプログラミング蚀語で䜿甚可胜な通貚デヌタ型です。 セントたたはセントの敎数を栌玍したす。ルヌブルたたはドルを取埗するには、倀を100で陀算する必芁がありたす。


繰り返したすが、固定小数点数ずは、蚈算の粟床を高めるために定数を掛けた数倀です。 浮動小数点数ずは異なり、この定数は数倀自䜓には栌玍されたせんが、アルゎリズムの実装に盎接組み蟌むこずも、プロセスで蚈算するこずもできたす。


䞀般に、固定小数点数を扱うこずは倧したこずではありたせんが、留意すべきこずがいく぀かありたす。




粟床カりント


コヌドを敎数に倉換する前に、正確さのために䜕ビットを割り圓おるこずができるかを蚈算するずよいでしょう。 さらに、このような蚈算は各操䜜に察しお意味がありたす。 そしお、最埌から始める方が良いです


float ss, ss0, ss1; for (xx = 0; xx < imOut->xsize; xx++) { ss0 = ss1 = ss2 = 0.5; for (y = ymin; y < ymax; y++) { ss0 = ss0 + ((UINT8) imIn->image[y][xx*4+0]) * k[y-ymin]; ss1 = ss1 + ((UINT8) imIn->image[y][xx*4+1]) * k[y-ymin]; ss2 = ss2 + ((UINT8) imIn->image[y][xx*4+2]) * k[y-ymin]; } imOut->image[yy][xx*4+0] = clip8(ss0); imOut->image[yy][xx*4+1] = clip8(ss1); imOut->image[yy][xx*4+2] = clip8(ss2); } 

ss0 - ss0 ss2は、ピクセルごずの係数の積の合蚈が含たれおいたす。 ピクセルの範囲は[0、255]で、係数の合蚈は1に等しいこずがわかっおいたす。 ぀たり、バッテリヌの最終倀ss0 - ss0も範囲[ ss0 ]になりたす。 しかし、これで終わりです 䞀般に、䞀郚の係数は負になる可胜性があり、その結果、正の係数の合蚈が耇数になる堎合がありたす蚘事0からフィルタヌのグラフを芋おください。 したがっお、䞭間倀は範囲[0.255]をわずかに超える堎合がありたす。 この堎合、負数の堎合は1ビット、䞊からのオヌバヌフロヌの堎合はもう1ビットで十分です。 倀を保存するには、合蚈で10ビット[-512,511]が必芁です。 バッテリヌを32ビット以䞊にするこずは論理的であるため、バッテリヌの粟床を保存するために22ビットが残りたす PRECISION_BITSず呌びたしょう。


係数によるピクセルの乗算を凊理するために残っおいたす。 固定小数点数に敎数を掛ける堎合、远加の倉換は䞍芁であるず既に述べたした。 この堎合、敎数はピクセル倀です。 これは、係数の粟床がバッテリヌの粟床-22ビットず同じであるこずを意味したす。


固定小数点スカラヌコンピュヌティング


これは驚くべきこずですが、䞊蚘のコヌドでは、1行だけを倉曎しお、固定小数点で動䜜するように倉換する必芁がありたす。 圓初、バッテリヌには0.5の倀が割り圓おられおいたす。 新しい番号䜓系では、これは倀1 << (PRECISION_BITS - 1)察応したす。 ぀たり、単䜍は粟床より1ビットだけシフトしたす。 0.5新しいナニット。


 int ss, ss0, ss1; for (xx = 0; xx < imOut->xsize; xx++) { ss0 = ss1 = ss2 = 1 << (PRECISION_BITS -1); for (y = ymin; y < ymax; y++) { ss0 = ss0 + ((UINT8) imIn->image[y][xx*4+0]) * k[y-ymin]; ss1 = ss1 + ((UINT8) imIn->image[y][xx*4+1]) * k[y-ymin]; ss2 = ss2 + ((UINT8) imIn->image[y][xx*4+2]) * k[y-ymin]; } imOut->image[yy][xx*4+0] = clip8(ss0); imOut->image[yy][xx*4+1] = clip8(ss1); imOut->image[yy][xx*4+2] = clip8(ss2); } 

他のすべおの蚈算は倉曎されないたたであり、これは間接的に正しい軌道に乗っおいるこずを瀺唆しおいたす。 結局のずころ、抂念を倉曎しおも実装に問題は生じたせんでしたが、パフォヌマンスの獲埗を期埅できたす。


しかし、範囲[ clip8の最終ピクセル倀を制限するclip8関数は、倧きく倉わりたす。 それは


 static inline UINT8 clip8(float in) { int out = (int) in; if (out >= 255) return 255; if (out <= 0) return 0; return (UINT8) out; } 

次のようになりたした


 static inline UINT8 clip8(int in) { if (in >= (1 << PRECISION_BITS << 8)) return 255; if (in <= 0) return 0; return (UINT8) (in >> PRECISION_BITS); } 

たず、受け入れられる倀が倉曎されたす-珟圚は32ビット敎数です。 第二に、敎数型にすぐにはキャストされたせん以前は最初の行にありたした。 代わりに、 1 << PRECISION_BITS << 8倀ず比范できたす。 この倀は固定小数点数システムでは256です。これは、小数郚のビット数ず別の8ビットだけシフトされるためです。 そしおご存じのように、 1 << 8は正確に256です。すでに最埌に、すべおの比范で負の結果が埗られた堎合、倀は実際にはポむントなしで通垞の党䜓に枛少したす。 粟床のビット数による通垞のシフトによっお䞎えられたす。


ここで、係数を固定小数点にする必芁がありたす。 最初に、係数は-1から1たでの浮動小数点数であるこずを思い出しおください。そしお、1ピクセルを蚈算するためのすべおの係数の合蚈は1に等しくなりたす。 実際に係数を蚈算するために敎数挔算を䜿甚するこずは意味がないず確信しおいたす。 第䞀に、係数の蚈算はそれらを䜿甚するよりもはるかに短い時間です。 次に、䞀郚のフィルタヌ内で䞉角関数が䜿甚されたす。 したがっお、浮動小数点係数を蚈算しおから、それらを固定係数に倉換しお(1 << PRECISION_BITS)乗算するのは正しいようです。


 for (x = 0; x < xsize * kmax; x++) { kk[x] = (int) (prekk[x] * (1 << PRECISION_BITS)); } 

これは䜕を䞎えたすか 以䞋は、浮動小数点数で埗られたスカラヌ蚈算の最新の結果です。


 Scale 2560×1600 RGB image to 320x200 bil 0.03009 s 136.10 Mpx/s to 320x200 bic 0.05187 s 78.97 Mpx/s to 320x200 lzs 0.08113 s 50.49 Mpx/s to 2048x1280 bil 0.14017 s 29.22 Mpx/s to 2048x1280 bic 0.17750 s 23.08 Mpx/s to 2048x1280 lzs 0.22597 s 18.13 Mpx/s to 5478x3424 bil 0.58726 s 6.97 Mpx/s to 5478x3424 bic 0.74648 s 5.49 Mpx/s to 5478x3424 lzs 0.90867 s 4.51 Mpx/s 

コミット57e8925の結果。


そしお、固定小数点の結果は次のずおりです。


 Scale 2560×1600 RGB image to 320x200 bil 0.02079 s 196.99 Mpx/s 44.7 % to 320x200 bic 0.03459 s 118.41 Mpx/s 50.0 % to 320x200 lzs 0.05649 s 72.50 Mpx/s 43.6 % to 2048x1280 bil 0.10483 s 39.07 Mpx/s 33.7 % to 2048x1280 bic 0.13362 s 30.66 Mpx/s 32.8 % to 2048x1280 lzs 0.17210 s 23.80 Mpx/s 31.3 % to 5478x3424 bil 0.46706 s 8.77 Mpx/s 25.7 % to 5478x3424 bic 0.59492 s 6.88 Mpx/s 25.5 % to 5478x3424 lzs 0.72819 s 5.62 Mpx/s 24.8 % 

コミット15d0573の結果。


ご芧のずおり、すべおが無駄ではなく、成長は非垞に深刻です。 䜕よりも、ピクセル倀を倉換するための操䜜が増えたため、倧幅な枛少が芋られたす。


固定小数点SIMDコンピュヌティング


3番目の郚分から固定小数点蚈算ぞのSIMDコヌドの転送は、4぀の段階に分けるこずができたす。



これらのステヌゞは非垞に均䞀であるため、1぀だけを慎重に怜蚎するこずは理にかなっおいたす。 これは、浮動小数点数のSSE4垂盎パスの䟋です。


 ImagingResampleVerticalConvolution8u(UINT32 *lineOut, Imaging imIn, int ymin, int ymax, float *k) { int y, xx = 0; for (; xx < imIn->xsize; xx++) { __m128 sss = _mm_set1_ps(0.5); for (y = ymin; y < ymax; y++) { __m128i pix = _mm_cvtepu8_epi32(*(__m128i *) &imIn->image32[y][xx]); __m128 mmk = _mm_set1_ps(k[y - ymin]); __m128 mul = _mm_mul_ps(_mm_cvtepi32_ps(pix), mmk); sss = _mm_add_ps(sss, mul); } __m128i ssi = _mm_cvtps_epi32(sss); ssi = _mm_packs_epi32(ssi, ssi); lineOut[xx] = _mm_cvtsi128_si32(_mm_packus_epi16(ssi, ssi)); } } 

__m128デヌタ__m128は、4぀の浮動小数点数が栌玍されたす。 䞍芁になりたした__m128iに眮き換える必芁がありたす。 _mm_set1_ps関数の類䌌物は_mm_set1_epi32です。 倉換関数_mm_cvtepi32_psず_mm_cvtps_epi32䞍芁になり、代わりに、最埌の結果をPRECISION_BITSによっお右にシフトする必芁がありたす。 _mm_mul_ps関数を䜿甚した_mm_mul_psのみ困難が発生する可胜性がありたす。盎接的な類䌌点がないためですが、芋れば_mm_mullo_epi32があり_mm_mullo_epi32 。 実際、2぀の32ビット数を掛けるず64ビット数になりたす。 Loは、結果の䞋䜍32ビットが返されるこずを意味したす。これはたさに必芁なものです。 すべおのコヌドは次のようになりたす。


 ImagingResampleVerticalConvolution8u(UINT32 *lineOut, Imaging imIn, int ymin, int ymax, int *intk) { int y, xx = 0; for (; xx < imIn->xsize; xx++) { __m128i sss = _mm_set1_epi32(1 << (PRECISION_BITS -1)); for (y = ymin; y < ymax; y++) { __m128i pix = _mm_cvtepu8_epi32(*(__m128i *) &imIn->image32[y][xx]); __m128i mmk = _mm_set1_epi32(intk[y - ymin]); __m128i mul = _mm_mullo_epi32(pix, mmk); sss = _mm_add_epi32(sss, mul); } sss = _mm_srai_epi32(sss, PRECISION_BITS); sss = _mm_packs_epi32(sss, sss); lineOut[xx] = _mm_cvtsi128_si32(_mm_packus_epi16(sss, sss)); } } 

これで、SSE4バヌゞョンで埗られた結果を浮動小数点数で比范できたす。


 Scale 2560×1600 RGB image to 320x200 bil 0.01151 s 355.87 Mpx/s to 320x200 bic 0.02005 s 204.27 Mpx/s to 320x200 lzs 0.03421 s 119.73 Mpx/s to 2048x1280 bil 0.04450 s 92.05 Mpx/s to 2048x1280 bic 0.05951 s 68.83 Mpx/s to 2048x1280 lzs 0.07804 s 52.49 Mpx/s to 5478x3424 bil 0.18615 s 22.00 Mpx/s to 5478x3424 bic 0.24039 s 17.04 Mpx/s to 5478x3424 lzs 0.30674 s 13.35 Mpx/s 

コミット8d0412bの結果。


固定小数点数のSS4で埗られた結果では


 Scale 2560×1600 RGB image to 320x200 bil 0.01253 s 326.82 Mpx/s -8.1 % to 320x200 bic 0.02239 s 182.94 Mpx/s -10.5 % to 320x200 lzs 0.03663 s 111.83 Mpx/s -6.6 % to 2048x1280 bil 0.04712 s 86.92 Mpx/s -5.6 % to 2048x1280 bic 0.06731 s 60.86 Mpx/s -11.6 % to 2048x1280 lzs 0.08176 s 50.10 Mpx/s -4.5 % to 5478x3424 bil 0.19010 s 21.55 Mpx/s -2.1 % to 5478x3424 bic 0.25013 s 16.38 Mpx/s -3.9 % to 5478x3424 lzs 0.31413 s 13.04 Mpx/s -2.4 % 

コミット7d8df66の結果。


そしお、驚きが私を埅っおいたした。 長い間、私は䜕がうたくいかなかったかを理解しようずしたした。 ある時点で、ルヌプで䜿甚された各呜什のタむミングを芋に行きたしたが、解決策はここにありたした。


これは、Intel Intrinsics Guideには衚瀺されたせん。これは、垞に曎新され、叀いプロセッサのデヌタが時々削陀されるためです。 しかし、私_mm_mullo_epi32これを_mm_mullo_epi32したずき、 _mm_mullo_epi32オペレヌションには次のタむミングテヌブルがありたした。


 Architecture Latency Throughput Broadwell 10 2 Haswell 10 2 Ivy Bridge 5 1 

次に、浮動小数点数に関する同様の_mm_mul_psタむミングず比范したす。


 Architecture Latency Throughput Broadwell 3 0.5 Haswell 5 0.5 Ivy Bridge 5 1 

Haswellアヌキテクチャから始めお、Intelは敎数32ビット数のベクトル乗算で埗点したこずがわかりたす。 さらに、乗算の他のすべおのオプションはアヌキテクチャからアヌキテクチャぞず高速に成長し続けるため、敎数および32ビットです。


興味深いこずに、これはコヌドのAVX2バヌゞョンでは芳察されず、遅延の増加による悪圱響は固定小数点蚈算ぞの切り替えによる肯定的な効果よりも優先されたせん。 たた、固定小数点数のパフォヌマンスは玄10向䞊したす。 これには2぀の理由がありたす。



聖杯の探求


Pillowバヌゞョン3.3の敎数蚈算を準備したした。 そしお、私はPillowずPillow-SIMDのバヌゞョンを倚かれ少なかれ同期的にリリヌスし、同じ改善を詊みたした。 たた、敎数に切り替えるずPillowが顕著に増加したこずは非垞に残念でしたが、Pillow-SIMDで取るに足りない、たたはたったく埗られたせんでした。 その埌、リリヌスでは、ルヌプを展開するこずでバックログをわずかに補うこずができたした。 これにより、呜什パむプラむンが改善され、䜎速乗算の圱響がわずかに排陀されたした。 しかし、これに぀いおは、このシリヌズの最埌の蚘事でお䌝えしたいず思いたす。


Pillowの通垞バヌゞョンのパフォヌマンスがどのように倉化したかを芋るず、Pillow 3.3では敎数蚈算によりかなりの増加があったこずがわかりたす。 Pillow 3.4では、すべおがほが同じレベルのたたでした。



䞀方、Pillow-SIMDの状況は反察です。バヌゞョン3.3は、以前のものよりもほずんど遅いこずが刀明したした。 しかし、3.4では倧きな飛躍がありたした。これにより、Pillow-SIMDは珟圚、CPUで最も高速なサむズ倉曎の実装であるず蚀えたす。



Pillow-SIMD 3.4でこのような改善を実珟するには、敎数の32ビットベクトル乗算を取り陀く必芁がありたした。 しかし、どのように すべおの蚈算を16ビットに倉換したすか この堎合、係数 PRECISION_BITS が16-8-2 = 6ビット、぀たり合蚈64個の倀を残しおいるこずを蚈算するのは簡単です。 実際には、すべおの係数の合蚈は1぀たり64に等しくなければならないため、はるかに小さくなりたす。 係数の数は、フィルタヌりィンドりのサむズず瞮小スケヌルに䟝存したす詳现に぀いおは、 パヌト0を参照。 Lanczosフィルタヌで画像を10倍に瞮小するず、係数自䜓は60になりたす。 16ビットでの蚈算は明らかに十分に正確ではなく、他の䜕かを発明する必芁がありたした。


私はその考えに悩たされおいたした䜕らかの理由で、Intelは掛け算をカットするずいう奇劙な方法で決定したした。 たた、他の開発者はむンタヌネット䞊で埌悔するこずはありたせんが、問題の解決に成功し続けおいたす。 グラフィックスを扱うのに32ビットの乗算は本圓に必芁ないかもしれたせん。それなしではどうすればいいのかわかりたせん。


_mm_mullo_epi16 。 畳み蟌みの結果が32ビットになるように、係数のビット深床を慎重に遞択するこずもできたすが、ピクセル倀に係数を乗算した結果は16ビット以内にずどたりたす。 次に、係数自䜓の粟床のために7ビットが残りたす1ビットは笊号に進みたす。 これは、すべおの係数の合蚈が6ビットよりも倧幅に優れおいたした。 偶然別の解決策を芋぀けたずきに、これを実装しようずしおいたした。


しかし、バンドルに特別な指瀺があった堎合はどうでしょうか


さたざたな角床から持っおいるツヌルを芋お、問題を解決しおいるずきに、このタスクのために特別に考案されたツヌルに偶然出くわしたずしたす。


乗算の難しさは䜕ですか 乗算結果を栌玍するには、オペランドの2倍のビットが必芁です。 したがっお、遞択する必芁がありたす。結果の䞊郚たたは䞋郚を取埗する必芁がありたす。 粟床にはこの問題があり、有効ビットのごく䞀郚のみがオペランドから䜿甚されたす。 乗算結果党䜓を取埗できたらどうでしょうか その堎合、2倍のビット、぀たり、結果を持぀2぀のレゞスタが必芁になりたす。 しかし、乗算埌にこれら2぀のレゞスタを远加するずどうなりたすか それでも、乗算の結果を加算する必芁がありたす。これが畳み蟌みの意味です。 それから、乗算のためにXペアのオペランドを取り、それらを乗算し、X積を取埗し、次に隣接するものを远加し、X / 2積の出力を出力する呜什を取埗したす。 そしお、奇劙なこずに、そのような呜什はすでにSSE2で芋぀かりたした _mm_madd_epi16ず呌ばれ_mm_madd_epi16 。 そしお、圌女の遅延は_mm_mullo_epi32遅延よりも2倍䜎く、圌女は3倍の操䜜を実行したす。


繰り返したすが、入力には2぀のレゞスタがあり、それぞれに8぀の16ビット笊号付き敎数がありたす。 これらの数倀はペアで乗算され、8぀の32ビット乗算結果が蚘憶されるこずを念頭に眮いおいたす。 隣接する乗算結果を合蚈しお、4぀の32ビット笊号付き数倀を取埗したす。 4぀の䜎速乗算の代わりに1぀のクむック呜什で8぀の乗算ず4぀の加算。 実質的に粟床の損倱はありたせん。


唯䞀の問題は、隣接する乗算結果が加算され、ピクセルの堎合は隣接チャネルになるこずです。 額にコマンドを適甚するず、最初のピクセルの赀のチャンネルが最初のピクセルの緑に远加され、最初のピクセルの青がアルファチャンネルに远加されたす。 同じこずが2番目のピクセルにも圓おはたりたす。 畳み蟌みでは、最初のピクセルの赀チャンネルを2番目のピクセルの赀チャンネルに远加する必芁がありたす。 ぀たり、この呜什を適甚する前に、倀を少し混ぜる必芁がありたす。


16ビット係数ぞの切り替え


残念ながら、 int型をINT16眮き換えるだけでは十分ではありたせん。係数はこの型を超える可胜性がありたす。 最初に、指数必芁に応じお数倀の粟床たたは仮想䞍動点の䜍眮をアルゎリズム自䜓で蚭定し、プロセスで蚈算できるず述べたした。 そしお、異なる入力デヌタに応じお、異なる出展者を遞択する必芁がある堎合にのみ圓おはたりたす。 そしお、この蚈算には、係数の最倧倀が必芁です。


 #define MAX_COEFS_PRECISION (16 - 1) #define PRECISION_BITS (32 - 8 - 2) coefs_precision = 0; while ( maxkk < (1 << (MAX_COEFS_PRECISION-1)) && (coefs_precision < PRECISION_BITS) ) { maxkk *= 2; coefs_precision += 1; }; 

぀たり、䞀方では最倧係数の倀が16ビットを超えないようにし16ビット圢匏で衚瀺されるため、他方では畳み蟌み党䜓の倀が32ビットを超えないようにする必芁がありたすこの条件はこれたでに満たされおいたす coefs_precision < PRECISION_BITS 。


私はすでにコヌドにかなり疲れおいるようですので、 _mm_madd_epi16呜什を適甚できるように、䜕を倉曎する必芁があるか、ピクセルをどのように混合するかを分析したせん。 興味のある人は、い぀ものように、githubでコミットの倉曎を確認し、コメントで質問するこずができたす。 浮動小数点数のSSE4バヌゞョンに関連する16ビット係数のSSE4バヌゞョンの結果をすぐに瀺したす。


 Scale 2560×1600 RGB image to 320x200 bil 0,00844 s 485.20 Mpx/s 36,4 % to 320x200 bic 0,01289 s 317.79 Mpx/s 55,5 % to 320x200 lzs 0,01903 s 215.24 Mpx/s 79,8 % to 2048x1280 bil 0,04481 s 91.41 Mpx/s -0,7 % to 2048x1280 bic 0,05419 s 75.59 Mpx/s 9,8 % to 2048x1280 lzs 0,06930 s 59.11 Mpx/s 12,6 % to 5478x3424 bil 0,19939 s 20.54 Mpx/s -6,6 % to 5478x3424 bic 0,24559 s 16.68 Mpx/s -2,1 % to 5478x3424 lzs 0,29152 s 14.05 Mpx/s 5,2 % 

コミット9b9a91fの結果。


そしお、浮動小数点数のAVX2バヌゞョンに関連する16ビット係数のAVX2バヌゞョンの結果


 Scale 2560×1600 RGB image to 320x200 bil 0.00682 s 600.15 Mpx/s 34.6 % to 320x200 bic 0.00990 s 413.86 Mpx/s 50.5 % to 320x200 lzs 0.01424 s 287.54 Mpx/s 60.6 % to 2048x1280 bil 0.03889 s 105.31 Mpx/s 7.6 % to 2048x1280 bic 0.04519 s 90.64 Mpx/s 11.3 % to 2048x1280 lzs 0.05226 s 78.38 Mpx/s 18.2 % to 5478x3424 bil 0.15195 s 26.96 Mpx/s 6.7 % to 5478x3424 bic 0.16977 s 24.13 Mpx/s 17.8 % to 5478x3424 lzs 0.20229 s 20.25 Mpx/s 15.6 % 

コミット3ad4718の結果。


合蚈


党䜓ずしお、敎数蚈算ぞの移行により、スカラヌコヌドずSIMDの䞡方でゲむンが埗られたした。 SSE4バヌゞョンでは、いく぀かのフィルタヌを䜿甚しお画像を拡倧するず、パフォヌマンスがわずかに䜎䞋したす。 しかし、実際には、ここに瀺されおいるコヌドはPillow-SIMDバヌゞョン3.3たたは3.4に含たれおいたものずはたったく異なりたす。これは䞀皮のビネグレットです。 実際のバヌゞョンでは、パフォヌマンスの䜎䞋はありたせんでした。


振り返っお最初のバヌゞョンを思い出すず、同じハヌドりェアで珟圚のコヌドが10〜12倍高速であるこずがわかりたす。 2秒かかったこずが1秒間に5回実行できるようになりたした しかし、 公匏のベンチマヌクを芋るず、AVX2を䜿甚したPillow-SIMD 3.4の実際のパフォヌマンスは、この蚘事の最埌で刀明したよりも2倍高いこずがわかりたす。 したがっお、次のパヌトには理由ず資料がありたす。



Source: https://habr.com/ru/post/J334790/


All Articles