mirror of
https://github.com/Nexoniarz/Finch.git
synced 2026-11-03 00:44:27 +00:00
Compiler and docs on every system: macOS Intel in CI, releases made by CI, docs for vectors and --cpu
- CI: macOS on Apple Silicon and Intel (macos-15, macos-15-intel); a tag v* attaches every package (Linux x64/ARM64, macOS ARM64/x64, Windows x64, the VS Code extension) to its release - vectors: fma is llvm.fmuladd (llvm.fma was a libm call per lane without FMA hardware: 3.5x slower) - examples/simd.fch: a dot product eight at a time, timed against the plain loop - README and the English guides: installing on Linux, macOS and Windows; vectors (SIMD); --cpu; -g is DWARF on Windows too (lldb from llvm-mingw); no more mention of the C++ compiler - comments left from the C++ compiler (src/target.cpp, src/codegen.cpp, "never frees") brought up to date Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Psc42moPLwP43Cmb9oZqSR
This commit is contained in:
parent
68a9493572
commit
0bf66740df
15 changed files with 463 additions and 171 deletions
69
examples/simd.fch
Normal file
69
examples/simd.fch
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
// Vectors (SIMD): eight f32 at once instead of one.
|
||||
//
|
||||
// finch run examples/simd.fch runs on any x86-64 or ARM64 processor
|
||||
// finch run examples/simd.fch --cpu native uses all of this one's instructions (AVX2, AVX-512, NEON)
|
||||
import time
|
||||
|
||||
// one number at a time
|
||||
fn dot_plain([]f32 a, []f32 b) -> f32 {
|
||||
f32 total = 0.0
|
||||
for i in 0..a.len {
|
||||
total += a[i] * b[i]
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
// eight at a time: f32x8(list, i) takes list[i] ... list[i+7], fma multiplies and adds in one step
|
||||
fn dot_simd([]f32 a, []f32 b) -> f32 {
|
||||
acc := f32x8(0.0)
|
||||
i := 0
|
||||
while i + 8 <= a.len {
|
||||
acc = f32x8(a, i).fma(f32x8(b, i), acc)
|
||||
i += 8
|
||||
}
|
||||
total := acc.sum()
|
||||
while i < a.len { // the few that are left
|
||||
total += a[i] * b[i]
|
||||
i += 1
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
// brighten every color: the same work on every lane, with min keeping it below 1
|
||||
fn brighten([]f32 pixels, f32 amount) {
|
||||
i := 0
|
||||
while i + 8 <= pixels.len {
|
||||
v := min(f32x8(pixels, i) * (1.0 + amount), 1.0)
|
||||
v.store(pixels, i)
|
||||
i += 8
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
[]f32 a
|
||||
[]f32 b
|
||||
for i in 0..4_000_000 {
|
||||
a.push(f32(i % 100) / 100.0)
|
||||
b.push(0.5)
|
||||
}
|
||||
|
||||
start := time.millis()
|
||||
x := 0.0
|
||||
for round in 0..20 {
|
||||
x = float(dot_plain(a, b))
|
||||
}
|
||||
plain := time.millis() - start
|
||||
|
||||
start = time.millis()
|
||||
y := 0.0
|
||||
for round in 0..20 {
|
||||
y = float(dot_simd(a, b))
|
||||
}
|
||||
simd := time.millis() - start
|
||||
|
||||
print("one at a time: ", str(x, 1), "in", plain, "ms")
|
||||
print("eight at a time:", str(y, 1), "in", simd, "ms")
|
||||
|
||||
brighten(a, 0.5)
|
||||
print("brightened:", a[10], a[90], a.len)
|
||||
}
|
||||
Loading…
Reference in a new issue