10000 OOP style for packet and link FFI structs by javierguerragiraldez · Pull Request #605 · snabbco/snabb · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
/ snabb Public
< 8000 div id="repository-details-container" class="flex-shrink-0" data-turbo-replace style="max-width: 70%;">

OOP style for packet and link FFI structs #605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

javierguerragiraldez
Copy link
Contributor

Many moons ago it was shown that OOP-style ffi.metatype() methods are just as fast as locally caching module functions like local l_empty = link.empty without the extra red tape and less risk of sub-par performance just because of wrongly guessing the impact of any given function.

This PR includes the methods for packet and link structs, and converts the basic_apps and keyed_ipv6_tunnel as examples.

@lukego
Copy link
Member
lukego commented Sep 2, 2015

@javierguerragiraldez Cool. I am in favor of this API style since your benchmarking campaign and I like the idea of using it pervasively.

I wonder whether it is better to do this piecemeal or in a "big bang" that defines a coherent API? I started that in #465 (Create a snabb module for core API) but never completed it. There are still some other interesting issues to consider in addition to function/method dispatching e.g. is it bad for packet.receive() to return an FFI pointer that may need to be heap-allocated and garbage collected?

re: performance implications we really need a performance regression test suite that can quantify these matters so that we don't have to make guesses in pull requests. That is actually the idea behind the snabbmark basic1 benchmark that runs simple source/sink/tee apps and SnabbBot will benchmark that on every PR and show whether the speed increases or decreases (latter is flagged as an error). So if part of the motivation for this change is to improve performance then I think it makes sense to also update the snabbmark basic1 benchmark so that SnabbBot can show us the performance impact.

@lukego
Copy link
Member
lukego commented Sep 7, 2015

Pondering this very interesting topic a bit more...

Overall I feel like it would be great to revise our core API and make it very efficient. Doing this well seems to require a fairly deep understanding of the limits of LuaJIT and the CPU. I am working on this in the background via my blogging, writing apps in assembler by hand (#603), improving the profiler to be able to compare our JIT'd code with the hand-written code (#611), and thinking about a unified facade for the API (#465).

I hope the result of these explorations will be a simple API that is hard to misuse and also some practical optimization and profiling tips to make it easy to get good and predictable performance.

There are a few specific issues that I want to address in the API:

  1. Use efficient function/method dispatch e.g. the FFI metatype style of this pull request.
  2. Keep API functions on-trace: avoid small branches/loops that can lead to side traces. (The "straightline" design seems great here: no looping over iovecs in the basic functions.)
  3. Keep API functions garbage-free: avoid allocations that might not be sunk e.g. returning freshly created FFI pointers from functions like link.receive() and packet.allocate().
  4. Make API performance robust to different compilation contexts e.g. fast for apps that loop in a single trace (able to "hoist" most work) and also fast for apps that are jumping between traces a lot (having to repreat a lot of work).

This is all probably quite simple once you have a strong enough mental model of LuaJIT but I feel like I am only around half of the way there.

Meanwhile it is hard to evaluate changes like this PR.

On the one hand it makes sense to merge code quickly if it is really having a measurable impact on a benchmark that we care about e.g. NFV packet forwarding. Is that the case? If so it would be interesting to know.

On the other hand I am cautious about merging piecemeal changes to the core API. Should everybody switch to the new syntax? Should all existing code be changed? Are we going to change this again in a short while when we understand LuaJIT better? These questions would all be easier to answer with a unified API update that comprehensively solves all the known problems of the existing API, rather than with individual extensions like adding a second way to call functions on packets and links.

Does this make sense?

Perhaps we need an Issue to start tracking the requirements for an updated API. I think that a bunch of us are making parallel investigations of LuaJIT behavior and coming up with theories of how the API and programming style should be adapted for better performance.

@lukego
Copy link
Member
lukego commented Oct 28, 2015

I don't think that master is the right place to land this PR. I see this as a step in the right direction towards a nicer core API but I would like to merge a whole API onto master and not only bits of it.

The trouble with the piecemeal approach is that in the short term it means more code, less consistency, and no more functionality.

Could be that we need a snabb-api-2.0 branch to collect API improvements and then actually apply them to the codebase before merging onto master? (kinda like we did with straight-line?) I would like to do this but don't have the time right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0