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

[huf] Reduce stack usage of HUF_readDTableX2 by ~972 bytes #2524

Merged
merged 4 commits into from
Mar 22, 2021

Conversation

terrelln
Copy link
Contributor

@terrelln terrelln commented Mar 5, 2021

  • Use HUF_readStats_wksp()
  • Use workspace in HUF_fillDTableX2*()
  • Clean up workspace usage to use a workspace struct
  • Move a 512 byte array in FSE_decompress_wksp() into the workspace.
  • Increase HUF_DECOMPRESS_WORKSPACE_SIZE by 512 bytes to accommodate the new array.

This reduces the decompression high water mark by 972 bytes.

* Use `HUF_readStats_wksp()`
* Use workspace in `HUF_fillDTableX2*()`
* Clean up workspace usage to use a workspace struct
* Move `counting` into the workspace
* Inrease `HUF_DECOMPRESS_WORKSPACE_SIZE` by 512 bytes
@terrelln terrelln changed the title [huf] Reduce stack usage of HUF_readDTableX2 by ~460 bytes [huf] Reduce stack usage of HUF_readDTableX2 by ~970 bytes Mar 11, 2021
@terrelln terrelln changed the title [huf] Reduce stack usage of HUF_readDTableX2 by ~970 bytes [huf] Reduce stack usage of HUF_readDTableX2 by ~972 bytes Mar 11, 2021
@Cyan4973
Copy link
Contributor

This is a good saving, and a nice refactor, especially when employing struct to replace pointer arithmetic.
There are just a few minor comments left, for the most part this PR is good.

* Move `counting` to a struct in `FSE_decompress_wksp_body()`
* Fix error code in `FSE_decompress_wksp_body()`
* Rename a variable in `HUF_ReadDTableX2_Workspace`
@terrelln
Copy link
Contributor Author

@Cyan4973 is this good to go?

@@ -310,6 +310,11 @@ size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size
return FSE_decompress_wksp_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, /* bmi2 */ 0);
}

typedef struct {
short count[FSE_MAX_SYMBOL_VALUE + 1];
} FSE_NormalizedCount;
Copy link
Contributor

@Cyan4973 Cyan4973 Mar 19, 2021

Choose a reason for hiding this comment

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

very minor :
I think I wasn't specific enough in my previous comment:
I was expecting a second struct member FSE_DTable dtable[1].

The point was to avoid pointer arithmetic to determine dtable.
Thus, instead of FSE_DTable* const dtable = (FSE_DTable*)(void*)((BYTE*)workSpace + sizeof(*ncount));,
it would rather be FSE_DTable* const dtable = &ncount.dtable;.

Having a last member of a struct as an array of size 1 is a known trick in C.
As the size is not enforced once the array decays as a pointer, it can effectively represent an array of any size.
Of course, sizeof(struct) is no longer correct then, since it's unaware of the real size of the array.
It's also not possible to stack anything after the array.

Some people prefer using an array of size [0] for this purpose,
which is indeed nice to make sizeof(struct) represent the size of members before the variable size array.
However, I read here and there that it could cause compatibility concerns with "some" compilers (though I don't know which one), hence I tend to use [1] to avoid such issue.
That being said, another consensus was that the size should represent the minimum expected size of the array,
thus [0] is relevant for an optional array that may be empty.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I wasn't sure if 0-sized arrays were a standard compliant feature or not. But I can give it a go and see if anything in CI complains.

@Cyan4973
Copy link
Contributor

Yes, that's fine.
I have one last comment, although it's more a suggestion than a blocking point.
Feel free to proceed as you feel is best.

@terrelln terrelln merged commit ebc2dfa into facebook:dev Mar 22, 2021
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.

3 participants