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

ordered_set: Leaner, faster, richer, safer. #3432

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

DoctorNoobingstoneIPresume
Copy link
Contributor

Previously, for each element, we used to allocate (and later deallocate)
two separate nodes:

  • a node inside a list (two link-pointers plus payload of two pointers);
  • a node inside a tree (three link-pointers plus one bool plus actual payload).

Now, we only allocate a single node:

  • a node inside a set (three link-pointers plus payload).

The payload of the node inside the set
contains the two link-pointers for list operations
and then the actual payload (an element of type T).

Benefits:

Side note:
We have preferred boost::container::set to std::set
because the former by default tries to merge the colour flag (a bool flag)
with one of the three links, therefore further reducing memory consumption.
TODO: Consider how this works in a World of Garbage Collection.

The current changeset is a draft -- not yet complete for the purposes of p4c,
but offering the essential features of ordered_set:
iteration in sorted order (now with backwards iteration as well)
and iteration in user-controlled (sequence) order.

It represents a proof of concept and a request for comments. (-:

Previously, for each element, we used to allocate (and later deallocate)
two separate nodes:

  - a node inside a list (two link-pointers plus payload of two pointers);
  - a node inside a tree (three link-pointers plus one bool plus actual payload).

Now, we only allocate a single node:

  - a node inside a set (three link-pointers plus payload).

The payload of the node inside the set
contains the two link-pointers for list operations
and then the actual payload (an element of type T).

Benefits:
  - fewer allocations/deallocations;
  - less memory consumed (the payload of two pointers in the list was wasteful);
  - better locality of data;
  - superiour error-safety guarantees
    (the intrusive container operations offer the strongest guarantee: nofail)
    (=> merging a fix such as PR p4lang#3294 is no longer needed);
  - improved speed.

Side note:
  We have preferred boost::container::set to std::set
  because the former by default tries to merge the colour flag (a bool flag)
  with one of the three links, therefore further reducing memory consumption.
  TODO: Consider how this works in a World of Garbage Collection.

The current changeset is a draft -- not yet complete for the purposes of p4c,
but offering the essential features of ordered_set:
iteration in sorted order (now with backwards iteration as well)
and iteration in user-controlled (sequence) order.

It represents a proof of concept and a request for comments. (-:
@onf-cla-manager
Copy link

Hi @DoctorNoobingstoneIPresume, this is the ONF bot 🤖 I'm glad you want to contribute to our projects! However, before accepting your contribution, we need to ask you to sign a Contributor License Agreement (CLA). You can do it online, it will take only a few minutes:

✒️ 👉 https://cla.opennetworking.org

After signing, make sure to add your Github user ID DoctorNoobingstoneIPresume to the agreement.

For more information or help:"
https://wiki.opennetworking.org/x/BgCUI

@mihaibudiu
Copy link
Contributor

This code does not compile in CI.

@DoctorNoobingstoneIPresume DoctorNoobingstoneIPresume marked this pull request as draft July 14, 2022 23:37
@fruffy
Copy link
Collaborator

fruffy commented Jan 16, 2023

Hi @DoctorNoobingstoneIPresume are you planning to continue work on this? It looks very useful.

Copy link
Contributor

@ChrisDodd ChrisDodd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where performance is a concern, I would expect that an hvec_set (based on hashvector.h similar to hvec_map) would be much more efficient.

@@ -17,234 17,540 @@ limitations under the License.
#ifndef _LIB_ORDERED_SET_H_
#define _LIB_ORDERED_SET_H_

#include <boost/container/set.hpp>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use boost::set rather than std::set -- the latter is more portable and reliable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please accept apologies for my replying late.

As explained in my first comment above, the Boost version of set attempts to merge the colour flag with one of the pointers => each node in the tree demands smaller block on the heap.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are in the processing of getting rid of boost in the compiler. On the other hand, we now have support for Abseil.

@@ -17,234 17,540 @@ limitations under the License.
#ifndef _LIB_ORDERED_SET_H_
#define _LIB_ORDERED_SET_H_

#include <boost/container/set.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/tuple/tuple.hpp>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should always use std::tuple rather than boost::tuple for better standards compliance.

MyEnlistedComp;

typedef
typename Alloc::template rebind <MyEnlistedNode>::other
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rebind is deprecated and removed in some newer compilers -- need to use rebind_alloc instead.

@DoctorNoobingstoneIPresume
Copy link
Contributor Author

Hi @DoctorNoobingstoneIPresume are you planning to continue work on this? It looks very useful.

Thank you so much... I have now remembered this -- and with joy, I dare say. I hope to, indeed, but need some time to get things back into my head.

Thank you for the kind message and the encouragement. It can make a difference in a community. ❤️

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.

4 participants