FastMath เป็นห้องสมุดคณิตศาสตร์ Delphi ที่ได้รับการปรับให้เหมาะสมสำหรับประสิทธิภาพที่รวดเร็ว (บางครั้งค่าใช้จ่ายในการไม่ทำการตรวจสอบข้อผิดพลาดหรือสูญเสียความแม่นยำเล็กน้อย) มันใช้รหัสแอสเซมบลีที่ปรับด้วยมือเพื่อให้ได้ประสิทธิภาพที่ดีขึ้นมากจากนั้นฟังก์ชั่นเทียบเท่าที่ได้รับจาก Delphi RTL
สิ่งนี้ทำให้ FastMath เหมาะสำหรับแอพพลิเคชั่นที่มีประสิทธิภาพสูงเช่นแอปพลิเคชันมัลติมีเดียและเกม เพื่อประสิทธิภาพที่ดียิ่งขึ้นไลบรารีให้ฟังก์ชั่น "โดยประมาณ" ที่หลากหลาย (ซึ่งทั้งหมดเริ่มต้นด้วย prefix Fast ) สิ่งเหล่านี้อาจเร็วมาก แต่คุณจะสูญเสียความแม่นยำบางอย่าง (บางครั้งก็น่าประหลาดใจ) สำหรับการเล่นเกมและแอนิเมชั่นการสูญเสียความแม่นยำนี้มักจะเป็นที่ยอมรับและเกินดุลโดยการเพิ่มความเร็ว อย่าใช้พวกเขาสำหรับการคำนวณทางวิทยาศาสตร์ ...
คุณอาจต้องการเรียก DisableFloatingPointExceptions ที่การเริ่มต้นแอปพลิเคชันเพื่อระงับข้อยกเว้นจุดลอยตัวใด ๆ แต่จะส่งคืนค่าสุดขีด (เช่นน่านหรืออินฟินิตี้) เมื่อไม่สามารถดำเนินการได้ หากคุณใช้ FastMath ในหลายเธรดคุณควรเรียก DisableFloatingPointExceptions ในบล็อก Execute ของเธรดเหล่านั้น
การดำเนินการส่วนใหญ่สามารถทำได้ทั้งค่าเอกพจน์ (สเกลาร์) และเวกเตอร์ (ประกอบด้วยค่า 2, 3 หรือ 4) รหัสประกอบที่ดีที่สุดของ SIMD ใช้เพื่อคำนวณเอาต์พุตหลายเอาต์พุตในเวลาเดียวกัน ตัวอย่างเช่นการเพิ่มเวกเตอร์ 4 ค่าสองตัวเข้าด้วยกันเกือบจะเร็วเท่ากับการเพิ่มค่าสองค่าเข้าด้วยกันทำให้ความเร็วเพิ่มขึ้น 4 เท่า ฟังก์ชั่นจำนวนมากถูกเขียนขึ้นในลักษณะที่การแสดงดียิ่งขึ้น
นี่คือตัวอย่างของปัจจัยความเร็วที่คุณคาดหวังบนแพลตฟอร์มที่แตกต่างกัน:
| RTL | เร็ว | x86-32 | x86-64 | ARM32 | ARM64 |
|---|---|---|---|---|---|
| TVECTOR3D + TVECTOR3D | TVECTOR4 + TVECTOR4 | 1.2x | 1.6x | 2.8x | 2.5x |
| ซิงเกิ้ล * TVECTOR3D | ซิงเกิ้ล * TVECTOR4 | 2.2x | 2.1x | 5.6x | 3.7x |
| TVector3d.length | TVector4.Length | 3.0x | 5.6x | 19.9x | 17.1x |
| TVector3d.normalize | TVector4.Normalize | 4.1x | 5.1x | 7.4x | 11.7x |
| TVECTOR3D * TMATRIX3D | TVECTOR4 * TMATRIX4 | 1.3x | 4.0x | 6.5x | 4.2x |
| tmatrix3d * tmatrix3d | tmatrix4 * tmatrix4 | 2.2x | 7.2x | 5.4x | 8.0x |
| tmatrix3d.inverse | tmatrix4.inverse | 9.8x | 9.2x | 8.0x | 9.8x |
| บาป (เดี่ยว) (x4) | Fastsin (TVector4) | 14.8x | 7.7x | 42.6x | 40.1x |
| Sincos (เดี่ยว) (x4) | FastSincos (TVector4) | 19.1x | 9.0x | 67.9x | 93.3x |
| exp2 (เดี่ยว) (x4) | FastExp2 (TVector4) | 22.4x | 32.7x | 275.0x | 302.4x |
อย่างที่คุณเห็นการดำเนินการที่พบบ่อยมาก (3D) เช่นการคูณเมทริกซ์และการผกผันอาจเร็วกว่ารุ่น RTL ที่สอดคล้องกันเกือบ 10 เท่า นอกจากนี้ FastMath ยังมีฟังก์ชั่นการประมาณ Fast* จำนวนมากที่เสียสละความแม่นยำเล็กน้อยสำหรับการเพิ่มความเร็วมหาศาล ตัวอย่างเช่นการใช้ FastSinCos ในการคำนวณฟังก์ชั่นไซน์และโคไซน์ 4 แบบขนานอาจเร็วกว่า 90 เท่าของฟังก์ชั่น RTL SinCos 4 ครั้งในขณะที่ยังคงให้ความแม่นยำที่ยอดเยี่ยมสำหรับมุมสูงถึง +/4000 เรเดียน (หรือ +/- 230,000 องศา)
บนแพลตฟอร์มเดสก์ท็อปขนาด 32 บิตและ 64 บิต (Windows และ OS X) ประสิทธิภาพนี้ทำได้โดยใช้ชุดคำสั่ง SSE2 ซึ่งหมายความว่าคอมพิวเตอร์จะต้องรองรับ SSE2 อย่างไรก็ตามเนื่องจาก SSE2 ได้รับการแนะนำกลับในปี 2544 คอมพิวเตอร์ส่วนใหญ่ที่ใช้ในปัจจุบันจะสนับสนุน คอมพิวเตอร์เดสก์ท็อป 64 บิตทั้งหมดได้รับการสนับสนุน SSE2 โดยค่าเริ่มต้น อย่างไรก็ตามคุณสามารถรวบรวมไลบรารีนี้ด้วย FM_NOSIMD กำหนดเพื่อปิดใช้งานการเพิ่มประสิทธิภาพ SIMD และใช้เวอร์ชัน Pascal ธรรมดา นอกจากนี้ยังมีประโยชน์ในการเปรียบเทียบความเร็วของเวอร์ชัน Pascal กับเวอร์ชันที่ปรับให้เหมาะสมของ SIMD
บนแพลตฟอร์มมือถือขนาด 32 บิต (iOS และ Android) ชุดคำสั่งนีออนใช้สำหรับการเพิ่มประสิทธิภาพ SIMD ซึ่งหมายความว่าอุปกรณ์ของคุณจำเป็นต้องรองรับนีออน แต่เนื่องจาก Delphi ต้องการสิ่งนี้แล้วสิ่งนี้จึงไม่มีข้อ จำกัด เพิ่มเติม
บนแพลตฟอร์มมือถือ 64 บิต (iOS) จะใช้ชุดคำสั่ง ARM64/ARCH64 SIMD
ไม่มีการสนับสนุนฮาร์ดแวร์เร่งความเร็วสำหรับ iOS Simulator (จะใช้เวอร์ชัน Pascal สำหรับการคำนวณทั้งหมด)
การดำเนินการ FastMath ในค่าจุดลอยตัวแบบเดียวเท่านั้น เลขคณิตลอยสองจุดที่มีความแม่นยำสองเท่าคือ (ปัจจุบัน) ไม่ได้รับการสนับสนุน
ฟังก์ชั่นส่วนใหญ่ทำงานกับค่าเดียว (ประเภท Single ) และเวกเตอร์ 2-, 3 และ 4 มิติ (ประเภท TVector2 , TVector3 และ TVector4 ตามลำดับ) เวกเตอร์ไม่เพียง แต่ใช้เพื่อแสดงจุดหรือทิศทางในอวกาศ แต่ยังสามารถถือได้ว่าเป็นอาร์เรย์ของค่า 2, 3 หรือ 4 ที่สามารถใช้ในการคำนวณแบบขนาน นอกเหนือจากเวกเตอร์จุดลอยตัวแล้วยังมีเวกเตอร์ที่โอเปอเรเตอร์เกี่ยวกับค่าจำนวนเต็ม ( TIVector2 , TIVector3 และ TIVector4 )
นอกจากนี้ยังมีการรองรับเมทริกซ์ 2x2, 3x3 และ 4x4 (เรียกว่า TMatrix2 , TMatrix3 และ TMatrix4 ) โดยค่าเริ่มต้นเมทริกซ์จะถูกเก็บไว้ในลำดับแถวที่สำคัญเช่นเดียวกับใน System.Math.Vectors ของ RTL อย่างไรก็ตามคุณสามารถเปลี่ยนเลย์เอาต์นี้ด้วย FM_COLUMN_MAJOR DEFINE สิ่งนี้จะจัดเก็บเมทริกซ์ในการสั่งซื้อคอลัมน์แทนแทนซึ่งมีประโยชน์สำหรับแอปพลิเคชัน OpenGL (ซึ่งทำงานได้ดีที่สุดกับเค้าโครงนี้) นอกจากนี้การกำหนดนี้จะตัดความลึกของเมทริกซ์กล้องถึง -1..1 แทนที่จะเป็นค่าเริ่มต้น 0..1 อีกครั้งนี้เป็นไปตามค่าเริ่มต้นสำหรับแอปพลิเคชัน OpenGL
สำหรับการเป็นตัวแทนของการหมุนในพื้นที่ 3 มิตินอกจากนี้ยังมี TQuaternion ซึ่งคล้ายกับประเภท TQuaternion3D ของ RTL
การทำงานของห้องสมุดได้รับแรงบันดาลใจจากภาษา Shader (เช่น GLSL และ HLSL) ในภาษาเหล่านั้นคุณยังสามารถรักษาค่าเดียวและเวกเตอร์ในทำนองเดียวกัน ตัวอย่างเช่นคุณสามารถใช้ฟังก์ชั่น Sin เพื่อคำนวณค่าไซน์เดียว แต่คุณสามารถใช้กับประเภท TVector4 เพื่อคำนวณค่าไซน์ 4 ค่าในการโทรเดียว เมื่อรวมกับฟังก์ชั่น Fast* โดยประมาณนี้อาจส่งผลให้ประสิทธิภาพเพิ่มขึ้นอย่างมากดังที่แสดงไว้ก่อนหน้านี้
ประเภทเวกเตอร์และเมทริกซ์ทั้งหมดรองรับตัวดำเนินการมากเกินไปซึ่งช่วยให้คุณสามารถลบล้างเพิ่มลบลบคูณและแบ่งสเกลาร์เวกเตอร์และเมทริกซ์
นอกจากนี้ยังมีตัวดำเนินการมากเกินไปที่เปรียบเทียบเวกเตอร์และเมทริกซ์เพื่อความเท่าเทียมกัน ผู้ประกอบการเหล่านี้ตรวจสอบการจับคู่ ที่แน่นอน (เช่น Delphi's = Operator) พวกเขา ไม่ อนุญาตให้มีการเปลี่ยนแปลงที่เล็กมาก (เช่นฟังก์ชั่น SameValue ของ Delphi)
ตัวดำเนินการเลขคณิต + , - , * และ / มักจะทำงานได้อย่างชาญฉลาดเมื่อนำไปใช้กับเวกเตอร์ ตัวอย่างเช่นหาก A และ B เป็นประเภท TVector4 , C := A * B จะตั้งค่า C เป็น (AX * BX, AY * BY, AZ * BZ, AW * BW) มันจะ ไม่ ดำเนินการ DOT หรือ Cross Product (คุณสามารถใช้ฟังก์ชัน Dot และ Cross เพื่อคำนวณเหล่านั้น)
สำหรับเมทริกซ์ตัวดำเนินการ + และ - ยังใช้งานส่วนประกอบที่ชาญฉลาด อย่างไรก็ตามเมื่อมีการคูณเมทริกซ์ (หรือหาร) ด้วยเวกเตอร์หรือเมทริกซ์อื่น ๆ จากนั้นใช้การคูณพีชคณิตเชิงเส้น (หรือการแบ่ง) ตามปกติ ตัวอย่างเช่น:
M := M1 * M2 ดำเนินการคูณเมทริกซ์เชิงเส้นเชิงเส้นV := M1 * V1 ทำเมทริกซ์ * การคูณพีชคณิตเชิงเส้นเวกเตอร์V := V1 * M1 ดำเนินการเวกเตอร์คอลัมน์ * การคูณพีชคณิตเชิงเส้นเมทริกซ์ ในการคูณเมทริกซ์ส่วนประกอบที่ชาญฉลาดคุณสามารถใช้วิธี CompMult
FastMath จัดหาเวกเตอร์และเมทริกซ์ของตัวเองเพื่อประสิทธิภาพที่เหนือกว่า ส่วนใหญ่มีค่าเทียบเท่ากับฟังก์ชันการทำงานและการจัดเก็บข้อมูลไปยังประเภท Delphi RTL คุณสามารถพิมพ์ดีดระหว่างพวกเขาหรือแปลงจากประเภท FastMath เป็นประเภท RTL หรือในทางกลับกัน (เช่น MyVector2 := MyPointF ) ตารางต่อไปนี้แสดงการแมป:
| วัตถุประสงค์ | เร็ว | Delphi RTL |
|---|---|---|
| 2d Point/Vector | TVector2 | tpointf |
| 3D Point/Vector | TVector3 | tpoint3d |
| 4D Point/Vector | TVector4 | TVector3d |
| เมทริกซ์ 2x2 | tmatrix2 | N/A |
| 3x3 เมทริกซ์ | tmatrix3 | tmatrix |
| เมทริกซ์ 4x4 | tmatrix4 | tmatrix3d |
| Quaternion | TQUATERNION | tquaternion3d |
เอกสารสามารถพบได้ใน HTML Help File FastMath.CHM ในไดเรกทอรี Doc
หรือคุณสามารถอ่านเอกสารออนไลน์ได้
ที่เก็บ FastMath เก็บไดเรกทอรีต่อไปนี้:
Doc : เอกสารในรูปแบบ htmlhelp นอกจากนี้ยังมีสเปรดชีต (benchmarks.xlsx) พร้อมผลลัพธ์ของการทดสอบประสิทธิภาพบนอุปกรณ์ของฉัน (เดสก์ท็อป core i7 และ iPad3)DocSource : มีไฟล์แบตช์สำหรับการสร้างเอกสาร คุณต้องใช้ Pasdocex เพื่อสร้างเอกสารด้วยตัวเองหากคุณต้องการFastMath : มีหน่วย Neslib.FastMath หลักรวมถึงไฟล์ต่าง ๆ รวมถึงไฟล์ที่มีการเพิ่มประสิทธิภาพเฉพาะโปรเซสเซอร์และไลบรารีคงที่พร้อมเวอร์ชันที่เหมาะสมที่สุดสำหรับ iOS และ AndroidArm : ซอร์สโค้ดเฉพาะและสคริปต์ ARMArm32 : มีซอร์สโค้ดแอสเซมบลีสำหรับฟังก์ชั่นที่ปรับให้เหมาะสมกับ NEON ARMArm64 : มีซอร์สโค้ดแอสเซมบลีสำหรับฟังก์ชั่นที่ดีที่สุดของ ARM64fastmath-android : มีไฟล์แบตช์และไฟล์ตัวช่วยเพื่อสร้างไลบรารีคงที่สำหรับ Android โดยใช้ Android NDKfastmath-ios : มีสคริปต์เชลล์ MacOS เพื่อสร้างไลบรารีสากลสากลสำหรับ iOSTests : มีแอปพลิเคชัน FireMonkey ที่เรียกใช้การทดสอบหน่วยและการทดสอบประสิทธิภาพ FastMath ได้รับใบอนุญาตภายใต้ใบอนุญาต BSD ที่เรียบง่าย ฟังก์ชั่นบางอย่างขึ้นอยู่กับรหัสของคนอื่นที่ได้รับอนุญาตภายใต้ใบอนุญาต MIT, BSD และ ZLIB ใหม่ ใบอนุญาตเหล่านั้นได้รับอนุญาตเช่นเดียวกับใบอนุญาต BSD ที่เรียบง่ายที่ใช้สำหรับโครงการทั้งหมด
ดู License.txt สำหรับรายละเอียด