- 并行編程方法與優化實踐
- 劉文志
- 1195字
- 2019-01-01 01:08:27
第1章 X86 SSE/AVX指令集
SSE/AVX是Intel公司設計的、對其X86體系的SIMD擴展指令集,它基于SIMD向量化技術,提高了X86硬件的計算能力,增強了X86多核向量處理器的圖像和視頻處理能力。
SSE/AVX指令支持向量化數據并行,一個指令可以同時對多個數據進行操作,同時操作的數據個數由向量寄存器的長度和數據類型共同決定。例如,SSE4向量寄存器(xmm)長度為128位,即16個字節,如果操作float或int數據,可同時操作4個,如果操作char數據,可同時操作16個。而AVX向量寄存器(ymm)長度為256位,即32字節,如果操作char類型數據,可同時操作32個,潛在地大幅度提升程序性能。
雖然SSE4/AVX指令向量寄存器的長度為128/256位,但是同樣支持64位長度的向量操作,64位向量映射到向量寄存器的前64位,這保證了兼容性。在64位程序下,SSE4/AVX向量寄存器的個數是16。
通常SSE指令要求訪問時內存地址對齊到向量長度,主要是為了減少內存或緩存操作的次數,如果內存地址沒有對齊到向量長度,則會增加訪問存儲器的次數。SSE4指令要求存儲器地址必須16字節對齊,而AVX指令最好也32字節對齊。SSE4及以前的SSE指令不支持不對齊的讀寫操作,為了簡化編程和擴大應用面,AVX指令集支持不對齊的讀寫,但是性能大約會下降20%。為了性能,在可能的情況下,還是應當使用對齊的讀寫操作。
SSE4/AVX加入了stream的概念,意為不使用緩存的讀寫,因為不使用緩存則留給其他讀取操作的緩存就多些,可能會提高性能。實際上這可能是一個“搬石頭砸自己腳”的技術,使用不好的話,可能會對程序性能有負面的影響。筆者并不是不建議使用它,而是讓讀者明白,使用它可能會適得其反,因此要特別注意。
Intel ICC和開源的GCC編譯器支持的SSE/AVX指令的C接口(intrinsic,內置函數)聲明在intrinsic.h頭文件中。其數據類型命名主要有__m128/__m256、__m128d/__m256i,默認為單精度(d表示雙精度,i表示整型)。其函數的命名可大致分為3個使用“_”隔開的部分,3個部分的含義如下。
·第一個部分為_mm或_mm256。_mm表示其為SSE指令,操作的向量長度為64位或128位。_mm256表示AVX指令,操作的向量長度為256位。本節只介紹128位的SSE指令和256位的AVX指令。
·第二個部分為操作函數名稱,如_add、_load、mul等,一些函數操作會增加修飾符,如loadu表示不對齊到向量長度的存儲器訪問。
·第三個部分為操作的對象名及數據類型,_ps表示操作向量中所有的單精度數據;_pd表示操作向量中所有的雙精度數據;_pixx表示操作向量中所有的xx位的有符號整型數據,向量寄存器長度為64位;_epixx表示操作向量中所有的xx位的有符號整型數據,向量寄存器長度為128位;_epuxx表示操作向量中所有的xx位的無符號整型數據,向量寄存器長度為128位;_ss表示只操作向量中第一個單精度數據;si128表示操作向量寄存器中的第一個128位有符號整型。
3個部分組合起來,就形成了一條向量函數,如_mm256_add_ps表示使用256位向量寄存器執行單精度浮點加法運算。
由于使用指令級數據并行,因此其粒度非常小,需要使用細粒度的并行算法設計。SSE/AVX指令集對分支的處理能力非常差,而從向量中抽取某些元素數據的代價又非常大,因此不適合含有復雜邏輯的運算。
- Python入門很簡單
- MySQL 8 DBA基礎教程
- Java面向對象程序開發及實戰
- C++ 從入門到項目實踐(超值版)
- 零基礎學Python網絡爬蟲案例實戰全流程詳解(高級進階篇)
- Java編程技術與項目實戰(第2版)
- Visual C#通用范例開發金典
- Learning Probabilistic Graphical Models in R
- PHP從入門到精通(第4版)(軟件開發視頻大講堂)
- Python大學實用教程
- Python入門很輕松(微課超值版)
- Scratch·愛編程的藝術家
- Simulation for Data Science with R
- IPython Interactive Computing and Visualization Cookbook
- Shopify Application Development