[FFmpeg-devel] [PATCH] avcodec/bsf: Avoid allocation for AVBSFInternal

zhilizhao quinkblack at foxmail.com
Tue Aug 11 02:27:14 EEST 2020



> On Aug 11, 2020, at 5:48 PM, Nicolas George <george at nsup.org> wrote:
> 
> Andreas Rheinhardt (12020-08-11):
>> Imagine the context to only contain elements that require a alignment of
>> 4 and the internal structure to require an alignment of eight. Then it
>> is perfectly possible for &ctx[1] to only have an alignment of four and
>> not of eight as internal requires it.
> 
> With this, you answered to James' question to me "What is undefined in
> that?".
> 
>> There are two reasons why I like my approach more than Mark's: It allows
> 
> I cannot find what you refer to "Mark's" approach.

Andreas referr to struct AVCodecHWConfigInternal with commit
24cc0a53e99.

> 
>> to hide the details of the context<->internal relationship to the place
>> where allocations happen (and if one asserted as Nicolas suggested
>> (av_assert2(ctx->internal == &((AVBSFCombined *)ctx)->internal), it
>> would also need to be visible for the function doing the freeing, but
>> even then it can still be confined to one file). After all, the internal
>> of several important other structures are in private headers to be used
>> by lots of code.
> 
> ... and therefore, I cannot understand exactly the point you are making
> here.
> 
>> The second point is another micro-optimization: If one puts the
>> AVBSFContext at the beginning of AVBSFInternal, then the offsets of all
>> the fields currently existing in AVBSFInternal will increase and the
>> encoding of the "read address from pointer + offset" is typically
>> shorter if offset is smaller. This is not a problem here as the
>> structures here are small, but other structures are bigger. This could
>> of course be overcome by putting the AVBSFContext at the end of
>> AVBSFInternal; but somehow this feels unnatural, although I could get
>> used to it.
> 
> In this, you are mistaken.
> 
> First, AFAIK, the increase in cost for accessing pointer+offset only
> happens at a few specific offsets, probably related to powers of two,
> which means the gain, minute as it is, only happens for the few fields
> that are pushed over the edge, if there are any.
> 
> But second, and most of all, you are neglecting a much more important
> optimization. If AVBSFContext is the first field of AVBSFInternal, then
> they both have the same address (it is explicitly specified in the spec,
> and it has been used for decades by Gtk+ for example), and therefore we
> can dispense with the ctx->internal pointer and just use it directly.
> 
> We can still have two pointers in the code, one for each type, to make
> it more compact and readable. But even if we do, the compiler will know
> they are the same.
> 
> Note that getting rid of the .internal field reduces the size of the
> structure, and is in itself another optimization.
> 
> And since we only have one pointer instead of two, it frees a register
> for other uses.
> 
> So this is an even better solution than your proposal, but it requires
> all uses of ->internal to be replaced. I I count correctly, that makes
> only four lines to change, and for a trivial change.
> 
> Note that all this can be done while keeping the specifics and the
> pointer magic hidden in a single file:
> 
>    static inline AVBSFInternal *bsf_internal(AVBSFContext *bsf) {
>        return (AVBSFInternal *)bsf;
>    }
> 
> Then the code only needs to write:
> 
>    AVBSFInternal *int = bsf_internal(bsf);
> 
> Regards,
> 
> -- 
>  Nicolas George
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".



More information about the ffmpeg-devel mailing list