SSE掩碼運算測試

2021-06-12 11:08:25 字數 3009 閱讀 9985

#if 1

// mmx, sse, sse2

#include #include #include #pragma comment(lib, "winmm.lib ")

// 用位掩碼做飽和處理.用求負生成掩碼

#define limitsu_fast(n, bits) ( (n) & -((n) >= 0) | -((n) >= (1<<(bits))) )

#define limitsu_safe(n, bits) ( (limitsu_fast(n, bits)) & ((1<<(bits)) - 1) )

#define limitsu_byte(n) ((byte)(limitsu_fast(n, 8)))

// 用位掩碼做飽和處理.用帶符號右移生成掩碼

#define limitsw_fast(n, bits) ( ( (n) | ((signed short)((1<<(bits)) - 1 - (n)) >> 15) ) & ~((signed short)(n) >> 15) )

#define limitsw_safe(n, bits) ( (limitsw_fast(n, bits)) & ((1<<(bits)) - 1) )

#define limitsw_byte(n) ((byte)(limitsw_fast(n, 8)))

// 資料規模

#define datasize 16384 // 128kb / (sizeof(signed short) * 4)

// 緩衝區。sse需要按128位對齊

__declspec(align(16)) signed short bufs[datasize*4]; // 源緩衝區。64位的顏色(4通道,每通道16位)

__declspec(align(16)) byte bufd[datasize*4]; // 目標緩衝區。32位的顏色(4通道,每通道8位)

// 測試時的函式型別

typedef void (*testproc)(byte* pbufd, const signed short* pbufs, int cnt);

// // sse系列指令集的支援級別. simd_sse_level 函式的返回值。

#define simd_sse_none 0 // 不支援

#define simd_sse_1 1 // sse

#define simd_sse_2 2 // sse2

#define simd_sse_3 3 // sse3

#define simd_sse_3s 4 // ssse3

#define simd_sse_41 5 // sse4.1

#define simd_sse_42 6 // sse4.2

const char* simd_sse_names = ;

// 是否支援mmx指令集

bool simd_mmx()

} __except (exception_execute_handler)

if ( v_edx & bit_dx_mmx )

return true;

} __except (exception_execute_handler)

}return false;

}// 檢測sse系列指令集的支援級別

int simd_sse_level()

} __except (exception_execute_handler)

if ( v_edx & bit_d_sse )}}

}} }

// check os support

__try }

__except (exception_execute_handler)

return rt;

}// 用if分支做飽和處理

void f0_if(byte* pbufd, const signed short* pbufs, int cnt)

}// 用min、max飽和處理

void f1_min(byte* pbufd, const signed short* pbufs, int cnt)

// next

ps += 2;

pd += 1;

} // mmx狀態置空

_mm_empty();

}// 飽和處理sse版

void f5_sse(byte* pbufd, const signed short* pbufs, int cnt)

// next

ps += 2;

pd += 1; }}

// 進行測試

void runtest(char* szname, testproc proc)

} // show

//tm1 = gettickcount() - tm0;

tm1 = timegettime() - tm0;

printf("%s[%d]:\t%.1f\n", szname, i, (double)tm1/nloop);

// check

//if (1==i)

// }}

int main(int argc, char* argv)

// 進行測試

//runtest("f0_if", f0_if);

//runtest("f1_min", f1_min);

//runtest("f2_neg", f2_neg);

//runtest("f3_sar", f3_sar);

if (simd_mmx()) runtest("f4_mmx", f4_mmx);

if (simd_sse_level()>=simd_sse_2) runtest("f5_sse", f5_sse);

// 結束前提示

if (argc<=1)

return 0;

}#endif

子網掩碼運算

定義子網掩碼 用於子網掩碼的位數決定於可能的子網數目和每個子網的主機數目。在定義子網掩碼前,必須弄清楚本來使用的子網數和主機數目。定義子網掩碼的步驟為 a 確定哪些組位址歸我們使用。比如我們申請到的網路號為 210.73.a.b 該網路位址為c類ip位址,網路標識為 210.73.a 主機標識為 b...

SSE2指令集系列之一 浮點運算指令

sse2與sse1使用相同暫存器,指令描述約定 mm指64位mmx暫存器 xmm指128xmm暫存器 m32 指32位記憶體變數 m128指128位記憶體變數 本小結主要描述雙精度浮點運算指令 1.資料搬移指令 movapdxmm,xmm m128 movapdxmm m128,xmm 把源儲存器內...

利用子網掩碼和位運算區分IP位址型別

根據rfc950定義,子網掩碼是乙個32位的2進製數,其對應網路位址的所有位都置為1,對應於主機位址的所有位都置為0。子網掩碼的設定必須遵循一定的規則。與二進位制ip位址相同,子網掩碼由1和0組成,且1和0分別連續。子網掩碼的長度也是32位,左邊是網路位,用二進位制數字 1 表示,1的數目等於網路位...