使用Java 18的Vector API提高效能 - martin
Java Vector API 為現代 CPU 的資料並行功能提供了一個抽象層。
由於不同的處理器架構有不同的風格,因此沒有簡單的解決方案來利用軟體中特定於平臺的功能。通常需要以特定於平臺的方式編寫程式碼並利用平臺的特定功能來獲得出色的效能優勢。Vector API 試圖使開發人員能夠以與平臺無關的方式編寫資料並行軟體。
這篇博文試圖在一些示例中探索新的 Vector API 提供的可能性,以及對於特定用例是否值得探索潛在的實現。
為了解釋 Java Vector API 抽象是如何工作的,我們需要探索不同的 CPU 架構並提供對資料平行計算的基本理解。然而,這個概念並不是那麼新。它在 C# 中已經存在了一段時間,並且已被證明是在現代硬體架構上利用資料平行計算的好方法。
與常規計算操作相比,如 1+1,在一次操作中新增兩個“資料”,資料並行操作是在多個“資料”上執行簡單的操作(例如,+)同時。這種操作模式稱為 SIMD(單指令,多資料),而傳統的執行方式稱為 SISD(單指令,單資料)。效能加速的結果是在一個 CPU 週期內對多個“資料”應用相同的操作。
由於處理器採用不同的 uArch(x86、ARM),它們的 SIMD 實現存在顯著差異。
簡單求和
從一個簡單的例子開始,我們可以詳細看看下面的程式碼片段:
public static int[] simpleSum(int[] a, int[] b) { var c = new int[a.length]; for (var i = 0; i < a.length; i++) { c[i] = a[i] + b[i]; } return c; } |
同樣的程式碼透過Vector API翻譯成資料並行加速程式碼:
private static final VectorSpecies<Integer> SPECIES = IntVector.SPECIES_PREFERRED; public static int[] vectorSum(int[] a, int[] b) { var c = new int[a.length]; var upperBound = SPECIES.loopBound(a.length); var i = 0; for (; i < upperBound; i += SPECIES.length()) { var va = IntVector.fromArray(SPECIES, a, i); var vb = IntVector.fromArray(SPECIES, b, i); var vc = va.add(vb); vc.intoArray(c, i); } // Compute elements not fitting in the vector alignment. for (; i < a.length; i++) { c[i] = a[i] + b[i]; } return c; } |
這段程式碼需要更多的說明。
在程式碼能夠執行並利用SIMD加速之前,必須確定資料寬度。AVX相容CPU可以處理256位元,而AVX-512可以提供512位元的資料寬度。
private static final VectorSpecies<Integer> SPECIES = IntVector.SPECIES_PREFERRED;
因此,我們需要正確配置迴圈的大小。簡單的for-loop使用i++將索引遞增1;在這個例子中,需要根據SIMD暫存器的資料寬度進行轉移。
在AVX-512(512位)上執行的整數運算的情況下,我們必須以16為單位遞增。
第一個迭代執行a[0]+b[0]到a[15]+b[15]的操作。
下一個操作對a[16]+b[16]到a[31]+b[31]執行同樣的操作,以此類推
//Determines the last index that fits the registers and cuts off any 'overhanging' items. var upperBound = SPECIES.loopBound(a.length); var i = 0; // Increment by the data-width! for (; i < upperBound; i += SPECIES.length()) { .... } |
最後,需要處理所有剩餘的專案,這些專案沒有在資料寬度內對齊。因此,該操作必須以非並行的方式進行,從第一個未被向量迴圈觸及的專案開始。
for (; i < a.length; i++) { // cleanup loop c[i] = a[i] + b[i]; } |
Vector API的程式碼可能看起來有點奇怪,但與我以前使用C的經驗相比,設計非常相似。
詳細點選標題
相關文章
- 提高API效能的幾個綜合策略API
- Java16的Vector API更好支援機器學習JavaAPI機器學習
- MapLibre/Martin | 使用Martin釋出MBTiles地圖切片包地圖
- 如何提高使用Java反射的效率?Java反射
- 使用 Traefik 提高 WebSocket 應用效能Web
- 如何使用 Set 來提高程式碼的效能
- vector的使用注意點
- 【譯】使用kotlin協程提高app效能KotlinAPP
- ElasticSearch Java API使用ElasticsearchJavaAPI
- ZooKeeper 使用 Java APIJavaAPI
- EasyExcel Java API 使用ExcelJavaAPI
- vector 使用 上
- java,netcore和nodejs api效能測試JavaNetCoreNodeJSAPI
- Java8的Stream API使用JavaAPI
- C++ 容器vector的使用C++
- Java效能優化:教你提高程式碼執行的效率Java優化
- 使用JsonTextReader提高Json.NET反序列化的效能JSON
- java arrayList vector 區別Java
- 【java】【集合】List、ListIterator、VectorJava
- Java集合系列(二):ArrayList、LinkedList、Vector的使用方法及區別Java
- 怎樣提高insert的效能
- 如何提高python程式的效能Python
- java api使用ElastichSearch指南JavaAPIAST
- 使用 Java 持久化 APIJava持久化API
- 使用 Java API 操作 elasticsearchJavaAPIElasticsearch
- java中的List介面(ArrayList、Vector、LinkedList)Java
- Java中Vector和ArrayList的區別Java
- hbase 2.0.2 java api的簡單使用JavaAPI
- 【語言】Java 日期 API 的使用技巧JavaAPI
- STL使用篇__vector
- 使用多執行緒提高rest服務效能執行緒REST
- Spark效能優化:提高並行度、使用reduceByKeySpark優化並行
- Java 18將指定UTF-8作為標準Java API的預設字符集JavaAPI
- 使用事件溯源提高了Elasticsearch的效能 - luis-sena事件ElasticsearchUI
- Java 18 新特性:使用Java程式碼啟動jwebserverJavaWebServer
- 如何提高 Locust 的壓測效能
- 伺服器的效能如何提高伺服器
- java中如何將巢狀迴圈效能提高500倍Java巢狀