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

[ML] Decrease the memory used by distribution models #146

Merged

Conversation

tveasey
Copy link
Contributor

@tveasey tveasey commented Jul 5, 2018

This makes some type changes to reduce precision of quantities where we don't need that precision. For example, this saves us around 15% of the memory typically used by the count residual distribution model (dropping from 1900 to 1650 bytes).

This may have a small affect on results simply due to slightly different rounding of floating point quantities.

@@ -42,7 +42,12 @@ using TCalendarComponentVec = std::vector<maths::CCalendarComponent>;
//! -# ContinuousData: which indicates the takes real values.
//! -# MixedData: which indicates the data can be decomposed into
//! some combination of the other three data types.
enum EDataType { E_DiscreteData, E_IntegerData, E_ContinuousData, E_MixedData };
enum EDataType : std::int32_t {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this actually making a difference on any platform? On all the platforms we support int is 32 bits. And I know gcc uses int for enums unless it's forced to do something different.

The C++ standard says that compilers can choose any integral type that can accommodate all the enum values to represent the enum type. But in practice they'll probably favour int as the C standard says the enum values must be int, and it would be foolish for a compiler vendor to introduce an incompatibility in the binary output for the same header file depending on whether it was compiled as C or C++.

So does clang or Visual C++ use a different enum size by default? If not, I think this is just introducing a distraction into the code without changing the end result.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok good point. I'd actually switched them to int8_t originally, but it caused knock on problems for printing them out which created more code churn. I'll double check and revert if it doesn't make a difference.

Choose a reason for hiding this comment

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

The other problem: Even if you force shrink the datatype like this (I agree int should be 32bit also on 64bit) you might not achieve the desired affect due to padding in the class instances where that is used.

(Do we correctly take padding into account in the memory usage calculations?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also shuffled some variable orders around so we would've benefited from shrinking these. I'm just doing a run now though to verify if we do actually get anything from this, I suspect Dave is right though and we don't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, we're using sizeof to get the size of these classes in the memory calculation (which include pads).

Copy link
Contributor

@droberts195 droberts195 Jul 5, 2018

Choose a reason for hiding this comment

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

(Do we correctly take padding into account in the memory usage calculations?)

We take padding between members of a single object into account, because we use sizeof(obj) rather than sizeof(member1) + sizeof(member2) + ....

What we don't take into account is allocator overhead. For example, if we ask for a 27 byte chunk of memory and the OS gives us a 32 byte chunk instead then we'll count 27 if sizeof(obj) is 27. And nor do we take into account any allocator data structures like pointers to the next block in a free list.

But model memory is only meant to be a rough estimate - getting it absolutely perfect would be incredibly hard and would involve having a very deep knowledge of what malloc() is doing on each platform.

Choose a reason for hiding this comment

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

👍

Maybe there are data structures which would benefit from disabling padding? If so we could try and see what are the savings in memory and what is the added runtime (hopefully not that bad).

Copy link
Contributor Author

@tveasey tveasey Jul 5, 2018

Choose a reason for hiding this comment

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

That's an interesting suggestion. I reordered variables in this change, so it should be able pack the types properly, but there may be other cases. Maybe something to look into down the line. The only slight caveat is it has been worthwhile shrinking these because of the upcoming change to model multi-bucket features will duplicate them per time series model. I suspect we may have smaller wins elsewhere.

@tveasey tveasey force-pushed the enhancement/reduce-distribution-model-memory branch from d0050a4 to de3f364 Compare July 5, 2018 14:41
Copy link
Contributor

@edsavage edsavage left a comment

Choose a reason for hiding this comment

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

A bit late to the party but LGTM

@tveasey tveasey merged commit 9f1a9cf into elastic:master Jul 6, 2018
tveasey added a commit to tveasey/ml-cpp-1 that referenced this pull request Jul 23, 2018
tveasey added a commit that referenced this pull request Jul 23, 2018
@tveasey tveasey deleted the enhancement/reduce-distribution-model-memory branch April 10, 2019 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants