通常因為三角函數或其他運算,使得 pixel 的運算結果出現小數點。
但很不幸的是,通常 pixel 只能是整數,所以必須將結果從浮點數轉為整數。
雖然有時候會有負數的運算,但這篇先暫時不討論,只研究正數的運算。
第一種作法: 整數 + 0.5
float f = 1.5; int i = static_cast<int>(f + 0.5f);
第二種做法: cmath library 的 roundf 函數
#include <cmath> float f = 1.5; int i = roundf(f);
第三種作法: Streaming SIMD Extensions (SSE) 指令內建函數
#include <xmmintrin.h> #include <emmintrin.h> float f = 1.5; int i = _mm_cvtss_si32(_mm_load_ss(&f));
Visual Studio 2015 關閉最佳化時,1億次迴圈的10次測試結果和平均:
Method | Method1 | Method2 | Method3 |
1 | 450.635 | 2863.75 | 651.554 |
2 | 277.212 | 2734.84 | 642.859 |
3 | 307.044 | 2847.59 | 637.882 |
4 | 322.505 | 2802.01 | 641.209 |
5 | 306.707 | 2853.88 | 642.388 |
6 | 313.872 | 2778.64 | 662.927 |
7 | 308.213 | 2762.08 | 635.335 |
8 | 326.224 | 2790.67 | 627.892 |
9 | 324.849 | 2744.77 | 650.551 |
10 | 306.833 | 2830.59 | 668.719 |
average | 324.409 | 2800.88 | 646.132 |
測試結果竟然和預期的不一樣Σ( ̄□ ̄|||)!!
我原本以為 SSE 指令的速度應該要是最快的。
不過看起來直接做 +0.5 運算的速度更快。
後來看了一下 ASM code,
第三種方法的 pointer 在 copy reference 的時候
和 __mm_cvtss_si32 和 _mm_load_ss 兩個 function 進出花了太多時間。
所以最後才會造成在速度上遠比直接做靜態轉換慢很多。
0 件のコメント:
コメントを投稿