Skip to content
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

C++ infra for bril #307

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open

C++ infra for bril #307

wants to merge 19 commits into from

Conversation

ryanwmao
Copy link
Contributor

C++ Infrastructure for Bril

Albert Xiao & Ryan Mao

Goal

Our primary aim was to enhance Bril's capabilities by incorporating a C++ interface, equipped with a parser, JSON printer, optimized types for instructions, and streamlined program flow mutations. The focus was squarely on performance, user-friendliness, and the potential to expand the Bril ecosystem with lightning-fast C++ optimizations.

Approach

We already built a basic C++ interface for our use in the assignments and exercises throughout the course. For our final project, we used this interface as a starting point, and aimed to build off of it to create a successful framework for Bril. First and foremost, we identified critical areas of our interface for improvement: shortcomings in memory safety, performance, and user-friendliness. Our strategy was twofold: retain certain functional aspects while fundamentally revamping the framework to align with our objectives.

Our initial phase involved a meticulous redesign of Bril's program types within our framework. We restructured our infrastructure around control flow graphs (CFG), because most optimizations operate at this level. This involved functionality to divide functions into basic blocks, and equipping program types with hooks to store analysis information for later optimization. We integrated data encapsulation into our types, in order to ensure memory safety and resistance to implementation changes.

After the foundational framework was set in place, we iteratively tested and enhanced its usability for implementing optimizations. We implemented a few trivial optimizations in order to evaluate the usability of our framework for implementing optimizations. By iteratively developing in this fashion, we were able to identify design issues and refine the final interface.

As a final touch to our framework, we also enhanced its performance and memory safety. This includes incorporating string pooling, representing strings with unique integers, and numbering basic blocks and variables with serial IDs. These optimizations enable us to use more efficient data structures like integer bitsets and arrays instead of the comparatively costly hashsets and hashmaps.

Challenges

The most demanding phase was establishing our foundational framework and planning for our improvements for the project. It required substantial time investment, especially in addressing all of the smaller issues and niche details. We frequently found that there were details that our initial plans did not cover, and we had to redesign our approach several times throughout the implementation process to accommodate for these issues.

Another critical challenge was striking a balance between the usability of our infrastructure and its optimization potential. The iterative process of testing and enhancing usability for implementing optimizations was very challenging, particularly because it was hard to view our framework from different perspectives to try and accommodate for different needs. Some of the implementation choices of our infrastructure were seemingly at odds with both of these goals; some design choices would be easier and more seamless to integrate with the functionality behind the scenes, but would be more difficult to interface with as a user, and vice versa.

Evaluation

Like the Rust library, we intended to implement the brili command as seamless replacements for the current implementations. Success was measured by ensuring these commands pass checks with valgrind and demonstrate comparable runtime performance to existing implementations. Ideally, we aimed to optimize these two programs within our framework to outperform all existing implementations.

For overall usability, we implemented part of partial redundancy elimination. We found that the optimization itself was too complicated, but we felt that our infrastructure was pretty decent to use. We didn’t really have a better way to evaluate this metric.

We found a few memory leaks with our final iteration but our program should still be memory safe.

For runtime performance, we ran the existing brili interpreter as well as our own interpreter against the core benchmarks in the course repo. We timed the wall clock runtime of both our interpreter and the existing interpreter over all benchmarks in the folder. We observe that we can obtain upwards of 10x improvement over the previous benchmark in wall clock runtime for some of the benchmarks. data.

@sampsyo
Copy link
Owner

sampsyo commented Dec 24, 2023

This is a pretty impressive setup, y'all!

Do you have a way to test your interpreter? For example, perhaps a Turnt configuration is possible that would compare the benchmarks against the reference interpreter. Being able to run this in CI would be a huge asset toward making sure this doesn't bitrot.

I also note that the library has vendored some headers from LLVM. I'm curious about the degree to which this is actually necessary—if we stick with standard C++ library stuff, we can avoid some of the longer-term issues that can arise with committing snapshots of externally-maintained code.

One last thing, if you're interested in including this in the main Bril monorepo: would y'all be interested in writing some documentation that explains to people how to use it? Some basic stuff like dependencies, build instructions, etc. would go a long way—no need for exhaustive API documentation, of course.

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.

3 participants