-
Notifications
You must be signed in to change notification settings - Fork 844
Perf: Fix mis-usage of Arena in HPACK #6495
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
Conversation
687b2eb to
93b9d1d
Compare
|
I'm worried about a size of the internal buffer and a length of the block chain in Arena. Using an arena for long time might have a similar issue with HdrHeap. |
|
What kind of memory behavior is required? How long do the encoded strings need to persist? |
|
All usage of Arena in the HPACK is allocating temporal strings. When the required buffer is small, we can use a buffer on the stack instead of Arena. ( it's another approach. ) The stored strings are freed at the end of function at longest. IIUC, unlike HdrHeap, allocated memory for Arena is re-used. The problem of HdrHeap is when the string in the HdrHeep is freed, the actual buffer was not freed. Similar things can happen to Arena? |
|
I didn't read the code closely so I may be wrong. The space seems like to be freed, but blocks are not. Once the chain gets long it never gets short, IIUC. |
|
The block will be reused if possible, so the worst case is requested string length keeps growing. When requested string length is 1byte to 128KB, the total allocated memory is 568KB (in 13 blocks). (128KB is default value of |
|
@SolidWallOfCode |
|
Well, not the |
|
The Temporary Allocation will cover this case well. No accumulation seems good. Let's use it when it backported. For now, let's land this change. Or if we really worry about the total size of Arena, we can go another approach like switching |
| if (len == -1) { | ||
| if (use_huffman && value_len) { | ||
| arena.str_free(data); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use https://github.com/apache/trafficserver/blob/master/include/tscpp/util/PostScript.h to avoid having to repeat this free 3 times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know we have this. I was thinking to introduce "defer" like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dr. Zret picked the name PostScript.
| } | ||
|
|
||
| return p - buf_start; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative to using an arena here would be something like:
template <std::size_t EstSizeBound = 1024>
class LocalBuffer
{
public:
LocalBuffer(std::size_t size) : _ptr(size > EstSizeBound ? new char[size] : _buf) {}
char * get() const { return _ptr; }
~LocalBuffer()
{
if (_ptr != buf) {
delete [] _ptr;
}
}
private:
char _buf[EstSizeBound];
char * const _ptr;
};
(Where 1024 is the default arena block size.). I'm guessing it would have better performance in the most likely scenarios.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks smarter than what I told as alternative approach (switching alloca & malloc ).
I agree with performance is better in most cases. I'll try this way.
|
#6536 looks much better on performance and no concern about memory accumulation. |
Arenais used for temporally buffer in some functions of HAPCK, but they are destroyed immediately. This is making some overhead of memory allocation. The arena should be reused.