→ fo40225: 要更快就要用unsafe去存取array與bitmap 12/17 22:46
真的有仔細看內文和稍微看一下專案的內容嗎...
※ 編輯: erspicu (61.70.74.143), 12/18/2015 00:18:49
→ fo40225: 我看了啊 看到都是用SetPixel 這就慢啊 12/18 12:55
HQX SCALE XBRZ這三個filter全都是用array在計算
你看到的GetPixel SetPixel 只是從bmp取出運算範例array
跟把計算好的結果寫入到bmp中 這兩部分完全不在效能評估的時間內
Stopwatch st = new Stopwatch();
st.Restart();
for (int i = 0; i < 2000; i++)
{
HS_XBRz.ScaleImage3X(array_org, array_3X, org_width, org_height);
}
st.Stop();
Console.WriteLine("all time : " + st.ElapsedMilliseconds);
int fps = (int)((double)2000 / ((double)st.ElapsedMilliseconds / (double)1000));
Console.WriteLine("fps : " + fps + "\r\n");
Bitmap bmp3x = new System.Drawing.Bitmap(org_width * 3, org_height * 3);
for (int i = 0; i < org_width * 3; i++)
for (int j = 0; j < org_height * 3; j++)
bmp3x.SetPixel(i, j, Color.FromArgb((int)(0xff000000 |
array_3X[i + j * org_width * 3])));
pictureBox3.Image = bmp3x;
如果你真的對這專案.議題.文章沒興趣,東西真的可以不需要看一半.
→ fo40225: .net4.6 x64可以用CPU SIMD加速 那些矩陣處理也可以更快 12/18 12:56
→ fo40225: 如果計算量夠大 用C++AMP寫邏輯給C#用可以比pfor快 12/18 12:59
文章開頭就寫到
"通常要求即時性的vidoe filter應該少會用全C#去實作,
不過一方面是為了好奇.一方面是挑戰C#效能極限.一方面是相容考量,"
然後下面推文寫說可以插C++進去.......
※ 編輯: erspicu (118.171.212.174), 12/18/2015 13:52:59
→ Litfal: 如果是相容考量,C++應該更好一些,不過得看你相容什麼XD 12/18 16:35
恩 相容的定義其實看那種性質的相容
→ Litfal: 然後filter系的優化,可以用動態產生IL的技巧,把一些不必 12/18 16:36
→ Litfal: 要的運算直接去掉,例如x1、x0、x-1這種在filter裡面常出 12/18 16:37
→ Litfal: 現的。直接動態產生IL的方式,我比較推薦Expression Tree 12/18 16:39
→ Litfal: 自己寫IL code有點辛苦,雖然有時是必要的... 12/18 16:39
IL code不太熟...不過我猜應該跟我之前k java bytecode大同小異
以後再慢慢看看....
→ fo40225: 文章 專案沒看懂是我的問題 抱歉 12/18 16:43
→ fo40225: 但我認為在ScaleImage內的操作 展開成那樣 12/18 16:45
→ fo40225: JIT的優化都沒了 還不如用unsafe + SIMD 可讀會回來一些 12/18 16:46
→ fo40225: 這樣也還算是在C#內實作吧?畢竟unsafe操作指標也是C#規格 12/18 16:47
→ fo40225: 如果操作array是瓶頸那就用unsafe去改 12/18 16:49
→ fo40225: 都用上pfor平行操作多筆資料了 用上SIMD一次操作更多不是 12/18 16:52
→ fo40225: 用pfor操作還有可能有CPU cache miss問題 12/18 16:57
→ fo40225: 展開減少stack push pop也可以試試MethodImplOptions 12/18 17:04
→ fo40225: MethodImplOptions.AggressiveInlining 12/18 17:04
method展開照理說會減少掉 stack的 cost ,但很奇怪太過量的展開有時候會有反效果..
原來跟JIT運作有關??
MethodImplOptions.AggressiveInlining 這東西我在改專案時有看到,
但不知道做啥的... 後來就把它自己手動開展了..而且這東西好像.NET 4.0沒有
直接指標又會比ARRAY再快些? 我再確認看看...感謝
不過說真的...這種優化處理問題,真的有心,要到達極致,堅持純C#的話,
真的跟我想的一樣,IL跟JIT都要挖下去...
照理說C#還真的比較少做這種事情..像影音編解碼.video filter等等,
多數是c/c++天下.
另外像是GPU的搭配,C#也比較少討論到... 有小玩一下C#+OPENCL做過些測試...
(用別人的套件...應該也是用INVOKE Native的方式)
沒寫好的話,光記憶體copy進入到vram,和vram copy出來到程式,
不然就是差不多時間,不然甚至更慢...
opencl 2.0 虛擬共享記憶體目前好像沒看到c#套件有支援到...
這些東西似乎又是另一個世界就是...
※ 編輯: erspicu (118.171.212.174), 12/18/2015 17:43:34