Skip to content

Commit

Permalink
FFI pointer object documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
mlochbaum committed Sep 25, 2024
1 parent 81b9be3 commit 0a79e89
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 32 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Looking for a modern, powerful language centered on Ken Iverson's array programm

- A simple, consistent, and [stable](commentary/stability.md) array programming language
- A low-dependency C implementation using bytecode compilation: [installation](running.md)
- [System functions](spec/system.md) for math, files, and I/O (including a C FFI)
- [System functions](spec/system.md) for math, files, and I/O (including a [C FFI](doc/ffi.md))
- [Documentation](doc/README.md) with examples, visuals, explanations, and rationale for features
- [Libraries](https://github.com/mlochbaum/bqn-libs) with interfaces for common file formats like JSON and CSV

Expand Down
1 change: 1 addition & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,6 @@ Primitives:
- [Windows: ``](windows.md)

Environment:
- [Foreign Function Interface (FFI)](ffi.md)
- [Embedded BQN](embed.md)
- [ReBQN](rebqn.md)
117 changes: 104 additions & 13 deletions doc/ffi.md

Large diffs are not rendered by default.

119 changes: 106 additions & 13 deletions docs/doc/ffi.html

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/doc/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ <h1 id="bqn-documentation"><a class="header" href="#bqn-documentation">BQN docum
</ul>
<p>Environment:</p>
<ul>
<li><a href="ffi.html">Foreign Function Interface (FFI)</a></li>
<li><a href="embed.html">Embedded BQN</a></li>
<li><a href="rebqn.html">ReBQN</a></li>
</ul>
2 changes: 1 addition & 1 deletion docs/implementation/perf.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ <h2 id="performance-resources"><a class="header" href="#performance-resources">P
</span></pre>
<p>CBQN also has a <code><span class='Paren'>)</span><span class='Value'>time</span></code> command that prints the time taken by an entire expression, not counting compilation time. And a <code><span class='Paren'>)</span><span class='Value'>profile</span></code> command that samples where time was spent by the line—execution naturally has to be spread over several lines for this to be useful, and should take at least a few milliseconds too.</p>
<p>The <a href="https://mlochbaum.github.io/bencharray/pages/summary.html">bencharray</a> tool has a page showing primitive benchmarks with some explanations.</p>
<p>If BQN isn't meeting your needs, there's always the option to hook up with C by FFI: see the <a href="../spec/system.html#foreign-function-interface-ffi">spec</a>. Also the <a href="https://github.com/dzaima/CBQN/blob/master/docs/system.md#ffi">CBQN docs</a>, which say how much of that is actually implemented now. FFI calls have low overhead (tens of nanoseconds), but may require copying as data goes in or out.</p>
<p>If BQN isn't meeting your needs, there's always the option to hook up with C by <a href="../doc/ffi.html">FFI</a>. FFI calls have low overhead (tens of nanoseconds), but may require copying as data goes in or out.</p>
<h2 id="versus-other-array-languages"><a class="header" href="#versus-other-array-languages">Versus other array languages</a></h2>
<p>Things get hard when you try to put array languages up next to each other. You can get completely different results depending on what sort of problems you want to solve and how you write code, and all those different results are valid. Because people ask for it, I'll try to give some description for the implementations I'm familiar with. I'm of course biased towards the languages I've worked on, Dyalog and BQN; if nothing else, these tend to prioritize just the features I find important! Note also that the situation can change over time; these comments are from 2023.</p>
<p>The implementations I use for comparison are Dyalog APL, ngn/k, and J. I don't benchmark against proprietary K implementations because the anti-benchmarking clauses in their licenses would prevent me from sharing the results (discussed <a href="kclaims.html">here</a>).</p>
Expand Down
2 changes: 1 addition & 1 deletion docs/implementation/versusc.html
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ <h3 id="dynamic-versus-static"><a class="header" href="#dynamic-versus-static">D
<p>We do a lot of dynamic checking in CBQN. Checking array rank and shape is pretty cheap, and we also track element type (see <a href="https://mlochbaum.github.io/BQN/implementation/compile/intro.html#and-which-is-better">this section</a>) and <a href="primitive/flagsort.html">sortedness</a> of arrays. A boolean array is packed 8 bits to the byte, which is way faster for most things but not often done in C.</p>
<p>There's also data-based checking, or <a href="https://en.wikipedia.org/wiki/Adaptive_algorithm">adaptive algorithms</a>—adaptive sorting being the best-known case. There are simpler examples too. <a href="primitive/replicate.html">Replicate</a> (<code><span class='Function'>/</span></code>) compares the input and output lengths to use either a sparse or dense algorithm, and can also check a boolean argument to see how many times it switches between 0 and 1, so that if it's clumpy it can copy values in chunks. Group (<code><span class='Function'></span></code>) checks for clumpiness as well, copying in sections if <code><span class='Value'>𝕨</span></code> changes value infrequently. Sticking to just a single implementation can lead to very poor cases that are dominated by branch misprediction penalties—which is exactly what happens in C when you write a string partitioning function that branches at the boundaries and then get a string where the sections are short.</p>
<h3 id="primitives-versus-c-libraries"><a class="header" href="#primitives-versus-c-libraries">Primitives versus C libraries</a></h3>
<p>BQN can call C code through its FFI, but it has a little call overhead and often requires copying data so it's not the fastest interface. C can also call into CBQN as a library, with similar issues. But isn't it possible to make C library functions for BQN primitives—in fact, don't many such library functions like sorting and binary searching already exist?</p>
<p>BQN can call C code through its <a href="../doc/ffi.html">FFI</a>, but it has a little call overhead and often requires copying data so it's not the fastest interface. C can also call into CBQN as a library, with similar issues. But isn't it possible to make C library functions for BQN primitives—in fact, don't many such library functions like sorting and binary searching already exist?</p>
<p>In principle this is a fine strategy; it's something we do a fair amount internally within BQN. Practically speaking, well first I have to admit that I know very little about these libraries. It seems clear enough that stdlib implementations are a joke as far as performance goes, so we are talking about C++ stuff like Abseil, Folly, or Boost. I'm still kind of skeptical, but what little knowledge I have about these is from looking at documentation and not finding functions that seemed useful (for implementing APL) and looking at source code and benchmarks and not seeing anything that seemed impressive. If anyone would, say, use these to implement some BQN primitives faster than CBQN's Singeli versions I'd change my mind real fast.</p>
<p>The advantage of a library is mainly moving from low level to high level. C libraries work within the static type system so they're still mainly static rather than dynamic, but can be dynamic in other ways like adaptive sorting. Beyond this I do have some examples few ways that the expectations for a C/C++ library tend to harm performance.</p>
<ul>
Expand Down
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ <h1 id="bqn-finally-an-apl-for-your-flying-saucer"><a class="header" href="#bqn-
<ul>
<li>A simple, consistent, and <a href="commentary/stability.html">stable</a> array programming language</li>
<li>A low-dependency C implementation using bytecode compilation: <a href="running.html">installation</a></li>
<li><a href="spec/system.html">System functions</a> for math, files, and I/O (including a C FFI)</li>
<li><a href="spec/system.html">System functions</a> for math, files, and I/O (including a <a href="doc/ffi.html">C FFI</a>)</li>
<li><a href="doc/index.html">Documentation</a> with examples, visuals, explanations, and rationale for features</li>
<li><a href="https://github.com/mlochbaum/bqn-libs">Libraries</a> with interfaces for common file formats like JSON and CSV</li>
</ul>
Expand Down
2 changes: 1 addition & 1 deletion implementation/perf.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ CBQN also has a `)time` command that prints the time taken by an entire expressi

The [bencharray](https://mlochbaum.github.io/bencharray/pages/summary.html) tool has a page showing primitive benchmarks with some explanations.

If BQN isn't meeting your needs, there's always the option to hook up with C by FFI: see the [spec](../spec/system.md#foreign-function-interface-ffi). Also the [CBQN docs](https://github.com/dzaima/CBQN/blob/master/docs/system.md#ffi), which say how much of that is actually implemented now. FFI calls have low overhead (tens of nanoseconds), but may require copying as data goes in or out.
If BQN isn't meeting your needs, there's always the option to hook up with C by [FFI](../doc/ffi.md). FFI calls have low overhead (tens of nanoseconds), but may require copying as data goes in or out.

## Versus other array languages

Expand Down
2 changes: 1 addition & 1 deletion implementation/versusc.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ There's also data-based checking, or [adaptive algorithms](https://en.wikipedia.

### Primitives versus C libraries

BQN can call C code through its FFI, but it has a little call overhead and often requires copying data so it's not the fastest interface. C can also call into CBQN as a library, with similar issues. But isn't it possible to make C library functions for BQN primitives—in fact, don't many such library functions like sorting and binary searching already exist?
BQN can call C code through its [FFI](../doc/ffi.md), but it has a little call overhead and often requires copying data so it's not the fastest interface. C can also call into CBQN as a library, with similar issues. But isn't it possible to make C library functions for BQN primitives—in fact, don't many such library functions like sorting and binary searching already exist?

In principle this is a fine strategy; it's something we do a fair amount internally within BQN. Practically speaking, well first I have to admit that I know very little about these libraries. It seems clear enough that stdlib implementations are a joke as far as performance goes, so we are talking about C++ stuff like Abseil, Folly, or Boost. I'm still kind of skeptical, but what little knowledge I have about these is from looking at documentation and not finding functions that seemed useful (for implementing APL) and looking at source code and benchmarks and not seeing anything that seemed impressive. If anyone would, say, use these to implement some BQN primitives faster than CBQN's Singeli versions I'd change my mind real fast.

Expand Down

0 comments on commit 0a79e89

Please sign in to comment.