diff mbox

Subject: [PATCH] [PATCH] time: tick-sched: use bool for tick_stopped

Message ID 891d4f632fbff5052e11f2d0b6fac35d@codeaurora.org (mailing list archive)
State Superseded, archived
Headers show

Commit Message

yuankuiz@codeaurora.org April 10, 2018, 7:33 a.m. UTC
From: John Zhao <yuankuiz@codeaurora.org>

Variable tick_stopped returned by tick_nohz_tick_stopped
can have only true / forse values. Since the return type
of the tick_nohz_tick_stopped is also bool, variable
tick_stopped nice to have data type as bool in place of int.
Moreover, the executed instructions cost could be minimal
without potiential data type conversion.

Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
---
  kernel/time/tick-sched.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Thomas Gleixner April 10, 2018, 7:55 a.m. UTC | #1
On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:

> From: John Zhao <yuankuiz@codeaurora.org>
> 
> Variable tick_stopped returned by tick_nohz_tick_stopped
> can have only true / forse values. Since the return type
> of the tick_nohz_tick_stopped is also bool, variable
> tick_stopped nice to have data type as bool in place of int.

The data type is not int. It's part of an integer bitfield and occupies
exactly one bit of storage, while bool has an architecture dependend size
and is at least 1 byte, i.e. 8 bit. So with alignment effects you grew the
size of the data structure and therefore the cache foot print.

This is not about 'nice to have' ....

Thanks,

	tglx
Rafael J. Wysocki April 10, 2018, 8 a.m. UTC | #2
On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
> From: John Zhao <yuankuiz@codeaurora.org>
>
> Variable tick_stopped returned by tick_nohz_tick_stopped
> can have only true / forse values. Since the return type
> of the tick_nohz_tick_stopped is also bool, variable
> tick_stopped nice to have data type as bool in place of int.
> Moreover, the executed instructions cost could be minimal
> without potiential data type conversion.
>
> Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
> ---
>  kernel/time/tick-sched.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
> index 6de959a..4d34309 100644
> --- a/kernel/time/tick-sched.h
> +++ b/kernel/time/tick-sched.h
> @@ -48,8 +48,8 @@ struct tick_sched {
>         unsigned long                   check_clocks;
>         enum tick_nohz_mode             nohz_mode;
>
> +       bool                            tick_stopped    : 1;
>         unsigned int                    inidle          : 1;
> -       unsigned int                    tick_stopped    : 1;
>         unsigned int                    idle_active     : 1;
>         unsigned int                    do_timer_last   : 1;
>         unsigned int                    got_idle_tick   : 1;

I don't think this is a good idea at all.

Please see https://lkml.org/lkml/2017/11/21/384 for example.

Thanks!
yuankuiz@codeaurora.org April 10, 2018, 8:12 a.m. UTC | #3
On 2018-04-10 03:55 PM, Thomas Gleixner wrote:
> On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
> 
>> From: John Zhao <yuankuiz@codeaurora.org>
>> 
>> Variable tick_stopped returned by tick_nohz_tick_stopped
>> can have only true / forse values. Since the return type
>> of the tick_nohz_tick_stopped is also bool, variable
>> tick_stopped nice to have data type as bool in place of int.
> 
> The data type is not int.
[ZJ] Yes. Per newest tip in branch of linux-pm-cpuidle, it is unsigned 
int with 1 bit in width.
There is typo in commit message, "int" at here should be "unsigned int"

> It's part of an integer bitfield and occupies
> exactly one bit of storage, while bool has an architecture dependend 
> size
> and is at least 1 byte, i.e. 8 bit. So with alignment effects you grew 
> the
> size of the data structure and therefore the cache foot print.
[ZJ] So, 1 bit in width is specified as:
+	bool				tick_stopped	: 1;
      This patch is based on the linux-pm-cpuidle branch which has
already gathered available space in the structure of tick_sched.

> 
> This is not about 'nice to have' ....
> 
> Thanks,
> 
> 	tglx
yuankuiz@codeaurora.org April 10, 2018, 8:15 a.m. UTC | #4
On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
> On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
>> From: John Zhao <yuankuiz@codeaurora.org>
>> 
>> Variable tick_stopped returned by tick_nohz_tick_stopped
>> can have only true / forse values. Since the return type
>> of the tick_nohz_tick_stopped is also bool, variable
>> tick_stopped nice to have data type as bool in place of int.
>> Moreover, the executed instructions cost could be minimal
>> without potiential data type conversion.
>> 
>> Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
>> ---
>>  kernel/time/tick-sched.h | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
>> index 6de959a..4d34309 100644
>> --- a/kernel/time/tick-sched.h
>> +++ b/kernel/time/tick-sched.h
>> @@ -48,8 +48,8 @@ struct tick_sched {
>>         unsigned long                   check_clocks;
>>         enum tick_nohz_mode             nohz_mode;
>> 
>> +       bool                            tick_stopped    : 1;
>>         unsigned int                    inidle          : 1;
>> -       unsigned int                    tick_stopped    : 1;
>>         unsigned int                    idle_active     : 1;
>>         unsigned int                    do_timer_last   : 1;
>>         unsigned int                    got_idle_tick   : 1;
> 
> I don't think this is a good idea at all.
> 
> Please see https://lkml.org/lkml/2017/11/21/384 for example.
[ZJ] Thanks for this sharing. Looks like, this patch fall into the case 
of "Maybe".

> 
> Thanks!
Thomas Gleixner April 10, 2018, 9:10 a.m. UTC | #5
On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
> On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
> > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
> > > From: John Zhao <yuankuiz@codeaurora.org>
> > > 
> > > Variable tick_stopped returned by tick_nohz_tick_stopped
> > > can have only true / forse values. Since the return type
> > > of the tick_nohz_tick_stopped is also bool, variable
> > > tick_stopped nice to have data type as bool in place of int.
> > > Moreover, the executed instructions cost could be minimal
> > > without potiential data type conversion.
> > > 
> > > Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
> > > ---
> > >  kernel/time/tick-sched.h | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
> > > index 6de959a..4d34309 100644
> > > --- a/kernel/time/tick-sched.h
> > > +++ b/kernel/time/tick-sched.h
> > > @@ -48,8 +48,8 @@ struct tick_sched {
> > >         unsigned long                   check_clocks;
> > >         enum tick_nohz_mode             nohz_mode;
> > > 
> > > +       bool                            tick_stopped    : 1;
> > >         unsigned int                    inidle          : 1;
> > > -       unsigned int                    tick_stopped    : 1;
> > >         unsigned int                    idle_active     : 1;
> > >         unsigned int                    do_timer_last   : 1;
> > >         unsigned int                    got_idle_tick   : 1;
> > 
> > I don't think this is a good idea at all.
> > 
> > Please see https://lkml.org/lkml/2017/11/21/384 for example.
> [ZJ] Thanks for this sharing. Looks like, this patch fall into the case of
> "Maybe".

This patch falls into the case 'pointless' because it adds extra storage
for no benefit at all.

Thanks,

	tglx
yuankuiz@codeaurora.org April 10, 2018, 10:07 a.m. UTC | #6
Hi Thomas,

On 2018-04-10 05:10 PM, Thomas Gleixner wrote:
> On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>> On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
>> > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
>> > > From: John Zhao <yuankuiz@codeaurora.org>
>> > >
>> > > Variable tick_stopped returned by tick_nohz_tick_stopped
>> > > can have only true / false values. Since the return type
>> > > of the tick_nohz_tick_stopped is also bool, variable
>> > > tick_stopped nice to have data type as bool in place of unsigned int.
>> > > Moreover, the executed instructions cost could be minimal
>> > > without potiential data type conversion.
>> > >
>> > > Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
>> > > ---
>> > >  kernel/time/tick-sched.h | 2 +-
>> > >  1 file changed, 1 insertion(+), 1 deletion(-)
>> > >
>> > > diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
>> > > index 6de959a..4d34309 100644
>> > > --- a/kernel/time/tick-sched.h
>> > > +++ b/kernel/time/tick-sched.h
>> > > @@ -48,8 +48,8 @@ struct tick_sched {
>> > >         unsigned long                   check_clocks;
>> > >         enum tick_nohz_mode             nohz_mode;
>> > >
>> > > +       bool                            tick_stopped    : 1;
>> > >         unsigned int                    inidle          : 1;
>> > > -       unsigned int                    tick_stopped    : 1;
>> > >         unsigned int                    idle_active     : 1;
>> > >         unsigned int                    do_timer_last   : 1;
>> > >         unsigned int                    got_idle_tick   : 1;
>> >
>> > I don't think this is a good idea at all.
>> >
>> > Please see https://lkml.org/lkml/2017/11/21/384 for example.
>> [ZJ] Thanks for this sharing. Looks like, this patch fall into the 
>> case of
>> "Maybe".
> 
> This patch falls into the case 'pointless' because it adds extra 
> storage
[ZJ] 1 bit vs 1 bit. no more.

> for no benefit at all.
[ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() which is 
bool.
The benefit is no any potiential type conversion could be minded.

> 
> Thanks,
> 
> 	tglx
Thomas Gleixner April 10, 2018, 11:06 a.m. UTC | #7
On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
> On 2018-04-10 05:10 PM, Thomas Gleixner wrote:
> > On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
> > > On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
> > > > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
> > > > > From: John Zhao <yuankuiz@codeaurora.org>
> > > > >
> > > > > Variable tick_stopped returned by tick_nohz_tick_stopped
> > > > > can have only true / false values. Since the return type
> > > > > of the tick_nohz_tick_stopped is also bool, variable
> > > > > tick_stopped nice to have data type as bool in place of unsigned int.
> > > > > Moreover, the executed instructions cost could be minimal
> > > > > without potiential data type conversion.
> > > > >
> > > > > Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
> > > > > ---
> > > > >  kernel/time/tick-sched.h | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
> > > > > index 6de959a..4d34309 100644
> > > > > --- a/kernel/time/tick-sched.h
> > > > > +++ b/kernel/time/tick-sched.h
> > > > > @@ -48,8 +48,8 @@ struct tick_sched {
> > > > >         unsigned long                   check_clocks;
> > > > >         enum tick_nohz_mode             nohz_mode;
> > > > >
> > > > > +       bool                            tick_stopped    : 1;
> > > > >         unsigned int                    inidle          : 1;
> > > > > -       unsigned int                    tick_stopped    : 1;
> > > > >         unsigned int                    idle_active     : 1;
> > > > >         unsigned int                    do_timer_last   : 1;
> > > > >         unsigned int                    got_idle_tick   : 1;
> > > >
> > > > I don't think this is a good idea at all.
> > > >
> > > > Please see https://lkml.org/lkml/2017/11/21/384 for example.
> > > [ZJ] Thanks for this sharing. Looks like, this patch fall into the case of
> > > "Maybe".
> > 
> > This patch falls into the case 'pointless' because it adds extra storage
> [ZJ] 1 bit vs 1 bit. no more.

Groan. No. Care to look at the data structure? You create a new storage,
which is incidentally merged into the other bitfield by the compiler at a
different bit position, but there is no guarantee that a compiler does
that. It's free to use distinct storage for that bool based bit.

> > for no benefit at all.
> [ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() which is bool.
> The benefit is no any potiential type conversion could be minded.

A bit stays a bit. 'bool foo : 1;' or 'unsigned int foo : 1' has to be
evaluated as a bit. So there is a type conversion from BIT to bool required
because BIT != bool.

By chance the evaluation can be done by evaluating the byte in which the
bit is placed just because the compiler knows that the remaining bits are
not used. There is no guarantee that this is done, it happens to be true
for a particular compiler.

But that does not make it any more interesting. It just makes the code
harder to read and eventually leads to bigger storage.

Thanks,

	tglx
Peter Zijlstra April 10, 2018, 11:26 a.m. UTC | #8
On Tue, Apr 10, 2018 at 06:07:17PM +0800, yuankuiz@codeaurora.org wrote:
> > > > > @@ -48,8 +48,8 @@ struct tick_sched {
> > > > >         unsigned long                   check_clocks;
> > > > >         enum tick_nohz_mode             nohz_mode;
> > > > >
> > > > > +       bool                            tick_stopped    : 1;
> > > > >         unsigned int                    inidle          : 1;
> > > > > -       unsigned int                    tick_stopped    : 1;
> > > > >         unsigned int                    idle_active     : 1;
> > > > >         unsigned int                    do_timer_last   : 1;
> > > > >         unsigned int                    got_idle_tick   : 1;
> > > >
> > > > I don't think this is a good idea at all.
> > > >
> > > > Please see https://lkml.org/lkml/2017/11/21/384 for example.
> > > [ZJ] Thanks for this sharing. Looks like, this patch fall into the
> > > case of
> > > "Maybe".
> > 
> > This patch falls into the case 'pointless' because it adds extra storage
> [ZJ] 1 bit vs 1 bit. no more.

Since its a different type, the bitfields will not be merged. Also I'm
surprised a bitfield with base-type _Bool is even allowed.

> > for no benefit at all.
> [ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() which is bool.
> The benefit is no any potiential type conversion could be minded.

Do you have any actual evidence for that? Is there a compiler stupid
enough to generate code to convert a bool to a 1bit value?
Thomas Gleixner April 10, 2018, 12:07 p.m. UTC | #9
On Tue, 10 Apr 2018, Peter Zijlstra wrote:

> On Tue, Apr 10, 2018 at 06:07:17PM +0800, yuankuiz@codeaurora.org wrote:
> > > > > > @@ -48,8 +48,8 @@ struct tick_sched {
> > > > > >         unsigned long                   check_clocks;
> > > > > >         enum tick_nohz_mode             nohz_mode;
> > > > > >
> > > > > > +       bool                            tick_stopped    : 1;
> > > > > >         unsigned int                    inidle          : 1;
> > > > > > -       unsigned int                    tick_stopped    : 1;
> > > > > >         unsigned int                    idle_active     : 1;
> > > > > >         unsigned int                    do_timer_last   : 1;
> > > > > >         unsigned int                    got_idle_tick   : 1;
> > > > >
> > > > > I don't think this is a good idea at all.
> > > > >
> > > > > Please see https://lkml.org/lkml/2017/11/21/384 for example.
> > > > [ZJ] Thanks for this sharing. Looks like, this patch fall into the
> > > > case of
> > > > "Maybe".
> > > 
> > > This patch falls into the case 'pointless' because it adds extra storage
> > [ZJ] 1 bit vs 1 bit. no more.
> 
> Since its a different type, the bitfields will not be merged. Also I'm
> surprised a bitfield with base-type _Bool is even allowed.
> 
> > > for no benefit at all.
> > [ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() which is bool.
> > The benefit is no any potiential type conversion could be minded.
> 
> Do you have any actual evidence for that? Is there a compiler stupid
> enough to generate code to convert a bool to a 1bit value?

Sure, if you do:

> > > > > > +       bool                            tick_stopped    : 1;

which is stupidly allowed by the standard....
Peter Zijlstra April 10, 2018, 12:26 p.m. UTC | #10
On Tue, Apr 10, 2018 at 02:07:32PM +0200, Thomas Gleixner wrote:
> On Tue, 10 Apr 2018, Peter Zijlstra wrote:
> > Do you have any actual evidence for that? Is there a compiler stupid
> > enough to generate code to convert a bool to a 1bit value?
> 
> Sure, if you do:
> 
> > > > > > > +       bool                            tick_stopped    : 1;
> 
> which is stupidly allowed by the standard....

The code-gen changes are because of the layout change, not because of
the type change.
Peter Zijlstra April 10, 2018, 12:33 p.m. UTC | #11
On Tue, Apr 10, 2018 at 10:00:01AM +0200, Rafael J. Wysocki wrote:
> On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
> > +++ b/kernel/time/tick-sched.h
> > @@ -48,8 +48,8 @@ struct tick_sched {
> >         unsigned long                   check_clocks;
> >         enum tick_nohz_mode             nohz_mode;
> >
> > +       bool                            tick_stopped    : 1;
> >         unsigned int                    inidle          : 1;
> > -       unsigned int                    tick_stopped    : 1;
> >         unsigned int                    idle_active     : 1;
> >         unsigned int                    do_timer_last   : 1;
> >         unsigned int                    got_idle_tick   : 1;
> 
> I don't think this is a good idea at all.
> 
> Please see https://lkml.org/lkml/2017/11/21/384 for example.

Joe, apw, could we get Checkpatch to whinge about _Bool in composite
types? That should immediately also disqualify using it as the base type
of bitfields.
yuankuiz@codeaurora.org April 10, 2018, 2:08 p.m. UTC | #12
On 2018-04-10 07:06 PM, Thomas Gleixner wrote:
> On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>> On 2018-04-10 05:10 PM, Thomas Gleixner wrote:
>> > On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>> > > On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
>> > > > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
>> > > > > From: John Zhao <yuankuiz@codeaurora.org>
>> > > > >
>> > > > > Variable tick_stopped returned by tick_nohz_tick_stopped
>> > > > > can have only true / false values. Since the return type
>> > > > > of the tick_nohz_tick_stopped is also bool, variable
>> > > > > tick_stopped nice to have data type as bool in place of unsigned int.
>> > > > > Moreover, the executed instructions cost could be minimal
>> > > > > without potiential data type conversion.
>> > > > >
>> > > > > Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
>> > > > > ---
>> > > > >  kernel/time/tick-sched.h | 2 +-
>> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
>> > > > >
>> > > > > diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
>> > > > > index 6de959a..4d34309 100644
>> > > > > --- a/kernel/time/tick-sched.h
>> > > > > +++ b/kernel/time/tick-sched.h
>> > > > > @@ -48,8 +48,8 @@ struct tick_sched {
>> > > > >         unsigned long                   check_clocks;
>> > > > >         enum tick_nohz_mode             nohz_mode;
>> > > > >
>> > > > > +       bool                            tick_stopped    : 1;
>> > > > >         unsigned int                    inidle          : 1;
>> > > > > -       unsigned int                    tick_stopped    : 1;
>> > > > >         unsigned int                    idle_active     : 1;
>> > > > >         unsigned int                    do_timer_last   : 1;
>> > > > >         unsigned int                    got_idle_tick   : 1;
>> > > >
>> > > > I don't think this is a good idea at all.
>> > > >
>> > > > Please see https://lkml.org/lkml/2017/11/21/384 for example.
>> > > [ZJ] Thanks for this sharing. Looks like, this patch fall into the case of
>> > > "Maybe".
>> >
>> > This patch falls into the case 'pointless' because it adds extra storage
>> [ZJ] 1 bit vs 1 bit. no more.
> 
> Groan. No. Care to look at the data structure? You create a new 
> storage,
[ZJ] Say, {unsigned int, unsigned int, unsigned int, unsigned int, 
unsigned int} becomes
           {bool        , unsigned int, unsigned int, unsigned int, 
unsigned int}
As specified by the rule No.10 at the section 6.7.2.1 of C99 TC2 as:
"If enough space remains, a bit-field that immediately follows another 
bit-field in a
structure shall be packed into adjacent bits of the same unit." What is 
the new storage so far?

> which is incidentally merged into the other bitfield by the compiler at 
> a
> different bit position, but there is no guarantee that a compiler does
> that. It's free to use distinct storage for that bool based bit.
[ZJ] Per the rule No.10 at section 6.7.2.1 of C99 TC2 as:
" If insufficient space remains, whether  a  bit-field  that  does  not  
fit  is  put  into
the  next  unit  or overlaps  adjacent  units  is 
implementation-defined."
So, implementation is never mind which type will be stored if any.

> >> > for no benefit at all.
>> [ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() which is 
>> bool.
>> The benefit is no any potiential type conversion could be minded.
> 
> A bit stays a bit. 'bool foo : 1;' or 'unsigned int foo : 1' has to be
> evaluated as a bit. So there is a type conversion from BIT to bool 
> required
> because BIT != bool.
[ZJ] Per the rule No.9 at section 6.7.2.1 of C99 TC2 as:
"If  the  value  0  or  1  is  stored  into  a  nonzero-width  bit-field 
  of  types
_Bool, the value of the bit-field shall compare equal to the value 
stored."
Obviously, it is nothing related to type conversion actually.
> 
> By chance the evaluation can be done by evaluating the byte in which 
> the
> bit is placed just because the compiler knows that the remaining bits 
> are
> not used. There is no guarantee that this is done, it happens to be 
> true
> for a particular compiler.
[ZJ] Actually, such as GCC owe that kind of guarantee to be promised by 
ABI.
> 
> But that does not make it any more interesting. It just makes the code
> harder to read and eventually leads to bigger storage.
[ZJ] To get the benctifit to be profiled, it is given as:
number of instructions of function tick_nohz_tick_stopped():
                         original: 17
                         patched:  14
      Which was saved is:
                movzbl	%al, %eax
                testl	%eax, %eax
                setne    %al
      Say, 3 / 17 = 17 % could be gained in the instruction executed for 
this function can be evaluated.

Note:
      The environment I used is:
                OS : Ubuntu Desktop 16.04 LTS
                gcc: 6.3.0                       (without optimization 
for in general purpose)

> 
> Thanks,
> 
> 	tglx
yuankuiz@codeaurora.org April 10, 2018, 2:49 p.m. UTC | #13
Typo...

On 2018-04-10 10:08 PM, yuankuiz@codeaurora.org wrote:
> On 2018-04-10 07:06 PM, Thomas Gleixner wrote:
>> On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>> On 2018-04-10 05:10 PM, Thomas Gleixner wrote:
>>> > On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>> > > On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
>>> > > > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
>>> > > > > From: John Zhao <yuankuiz@codeaurora.org>
>>> > > > >
>>> > > > > Variable tick_stopped returned by tick_nohz_tick_stopped
>>> > > > > can have only true / false values. Since the return type
>>> > > > > of the tick_nohz_tick_stopped is also bool, variable
>>> > > > > tick_stopped nice to have data type as bool in place of unsigned int.
>>> > > > > Moreover, the executed instructions cost could be minimal
>>> > > > > without potiential data type conversion.
>>> > > > >
>>> > > > > Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
>>> > > > > ---
>>> > > > >  kernel/time/tick-sched.h | 2 +-
>>> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
>>> > > > >
>>> > > > > diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
>>> > > > > index 6de959a..4d34309 100644
>>> > > > > --- a/kernel/time/tick-sched.h
>>> > > > > +++ b/kernel/time/tick-sched.h
>>> > > > > @@ -48,8 +48,8 @@ struct tick_sched {
>>> > > > >         unsigned long                   check_clocks;
>>> > > > >         enum tick_nohz_mode             nohz_mode;
>>> > > > >
>>> > > > > +       bool                            tick_stopped    : 1;
>>> > > > >         unsigned int                    inidle          : 1;
>>> > > > > -       unsigned int                    tick_stopped    : 1;
>>> > > > >         unsigned int                    idle_active     : 1;
>>> > > > >         unsigned int                    do_timer_last   : 1;
>>> > > > >         unsigned int                    got_idle_tick   : 1;
>>> > > >
>>> > > > I don't think this is a good idea at all.
>>> > > >
>>> > > > Please see https://lkml.org/lkml/2017/11/21/384 for example.
>>> > > [ZJ] Thanks for this sharing. Looks like, this patch fall into the case of
>>> > > "Maybe".
>>> >
>>> > This patch falls into the case 'pointless' because it adds extra storage
>>> [ZJ] 1 bit vs 1 bit. no more.
>> 
>> Groan. No. Care to look at the data structure? You create a new 
>> storage,
> [ZJ] Say, {unsigned int, unsigned int, unsigned int, unsigned int,
> unsigned int} becomes
>           {bool        , unsigned int, unsigned int, unsigned int, 
> unsigned int}
> As specified by the rule No.10 at the section 6.7.2.1 of C99 TC2 as:
> "If enough space remains, a bit-field that immediately follows another
> bit-field in a
> structure shall be packed into adjacent bits of the same unit." What
> is the new storage so far?
> 
>> which is incidentally merged into the other bitfield by the compiler 
>> at a
>> different bit position, but there is no guarantee that a compiler does
>> that. It's free to use distinct storage for that bool based bit.
> [ZJ] Per the rule No.10 at section 6.7.2.1 of C99 TC2 as:
> " If insufficient space remains, whether  a  bit-field  that  does
> not  fit  is  put  into
> the  next  unit  or overlaps  adjacent  units  is 
> implementation-defined."
> So, implementation is never mind which type will be stored if any.
> 
>> >> > for no benefit at all.
>>> [ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() which 
>>> is bool.
>>> The benefit is no any potiential type conversion could be minded.
>> 
>> A bit stays a bit. 'bool foo : 1;' or 'unsigned int foo : 1' has to be
>> evaluated as a bit. So there is a type conversion from BIT to bool 
>> required
>> because BIT != bool.
> [ZJ] Per the rule No.9 at section 6.7.2.1 of C99 TC2 as:
> "If  the  value  0  or  1  is  stored  into  a  nonzero-width
> bit-field  of  types
> _Bool, the value of the bit-field shall compare equal to the value 
> stored."
> Obviously, it is nothing related to type conversion actually.
>> 
>> By chance the evaluation can be done by evaluating the byte in which 
>> the
>> bit is placed just because the compiler knows that the remaining bits 
>> are
>> not used. There is no guarantee that this is done, it happens to be 
>> true
>> for a particular compiler.
> [ZJ] Actually, such as GCC owe that kind of guarantee to be promised by 
> ABI.
>> 
>> But that does not make it any more interesting. It just makes the code
>> harder to read and eventually leads to bigger storage.
> [ZJ] To get the benctifit to be profiled, it is given as:
> number of instructions of function tick_nohz_tick_stopped():
[ZJ] Here, I used is not the tick_nohz_tick_stopped(), but an 
evaluation() as:
#include <stdio.h>
#include <stdbool.h>

struct tick_sched {
         unsigned int inidle             : 1;
         unsigned int tick_stopped       : 1;
};

bool get_status()
{
         struct tick_sched *ts;
         ts->tick_stopped = 1;
         return ts->tick_stopped;
}

int main()
{
         if (get_status()) return 0;
         return 0;
}

[ZJ] Toggle the declaration of tick_stopped in side of the tick_sched 
structure for comparison.


>                         original: 17
>                         patched:  14
>      Which was saved is:
>                movzbl	%al, %eax
>                testl	%eax, %eax
>                setne    %al
>      Say, 3 / 17 = 17 % could be gained in the instruction executed
> for this function can be evaluated.
> 
> Note:
>      The environment I used is:
>                OS : Ubuntu Desktop 16.04 LTS
>                gcc: 6.3.0                       (without optimization
> for in general purpose)
> 
>> 

Just FYI.

Thanks,
ZJ
Joe Perches April 10, 2018, 3:14 p.m. UTC | #14
On Tue, 2018-04-10 at 14:33 +0200, Peter Zijlstra wrote:
> On Tue, Apr 10, 2018 at 10:00:01AM +0200, Rafael J. Wysocki wrote:
> > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
> > > +++ b/kernel/time/tick-sched.h
> > > @@ -48,8 +48,8 @@ struct tick_sched {
> > >         unsigned long                   check_clocks;
> > >         enum tick_nohz_mode             nohz_mode;
> > > 
> > > +       bool                            tick_stopped    : 1;
> > >         unsigned int                    inidle          : 1;
> > > -       unsigned int                    tick_stopped    : 1;
> > >         unsigned int                    idle_active     : 1;
> > >         unsigned int                    do_timer_last   : 1;
> > >         unsigned int                    got_idle_tick   : 1;
> > 
> > I don't think this is a good idea at all.
> > 
> > Please see https://lkml.org/lkml/2017/11/21/384 for example.
> 
> Joe, apw, could we get Checkpatch to whinge about _Bool in composite
> types? That should immediately also disqualify using it as the base type
> of bitfields.

Whinging about bool <foo> : <x> seems entirely sensible
and straightforward to do.

I'm not so sure about bool in structs as a patch context
could be adding a bool to local stack definitions and
there's no real ability to determine if the bool is in a
struct or on the stack.

Also, I think there's nothing really wrong with using
bool in structs.  Steven Rostedt's rationale in
https://lkml.org/lkml/2017/11/21/207 isn't really right
as sizeof(int) is 4 not 1 and sizeof(bool) is 1 on arches
without alignment issues.  I believe when using gcc,
sizeof(bool) is always 1 and there may be alignment padding
added on some arches.  Dunno.

But I think the battle is already lost anyway.

git grep -P  '(?<!static|extern)\s+bool\s+\w+\s*;' include | wc -l
1543
Peter Zijlstra April 10, 2018, 4:30 p.m. UTC | #15
On Tue, Apr 10, 2018 at 08:14:54AM -0700, Joe Perches wrote:
> Whinging about bool <foo> : <x> seems entirely sensible
> and straightforward to do.
> 
> I'm not so sure about bool in structs as a patch context
> could be adding a bool to local stack definitions and
> there's no real ability to determine if the bool is in a
> struct or on the stack.
> 
> Also, I think there's nothing really wrong with using
> bool in structs.  Steven Rostedt's rationale in
> https://lkml.org/lkml/2017/11/21/207 isn't really right
> as sizeof(int) is 4 not 1 and sizeof(bool) is 1 on arches
> without alignment issues.  I believe when using gcc,
> sizeof(bool) is always 1 and there may be alignment padding
> added on some arches.  Dunno.

C std simply does not define sizeof(_Bool) and leaves it up to
architecture ABI, therefore I refuse to use _Bool in composite types,
because I care about layout.

Also, not all architectures can do byte addressing, see Alpha <EV56
and for those _Bool would have to be a whole word (the existence of such
architectures likely influenced the vague definition of _Bool in the
first place).

> But I think the battle is already lost anyway.
> 
> git grep -P  '(?<!static|extern)\s+bool\s+\w+\s*;' include | wc -l
> 1543

Yes I know, doesn't mean we shouldn't discourage it for new code; also Linus.
yuankuiz@codeaurora.org April 10, 2018, 11:09 p.m. UTC | #16
++

On 2018-04-10 10:49 PM, yuankuiz@codeaurora.org wrote:
> Typo...
> 
> On 2018-04-10 10:08 PM, yuankuiz@codeaurora.org wrote:
>> On 2018-04-10 07:06 PM, Thomas Gleixner wrote:
>>> On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>>> On 2018-04-10 05:10 PM, Thomas Gleixner wrote:
>>>> > On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>>> > > On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
>>>> > > > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
>>>> > > > > From: John Zhao <yuankuiz@codeaurora.org>
>>>> > > > >
>>>> > > > > Variable tick_stopped returned by tick_nohz_tick_stopped
>>>> > > > > can have only true / false values. Since the return type
>>>> > > > > of the tick_nohz_tick_stopped is also bool, variable
>>>> > > > > tick_stopped nice to have data type as bool in place of unsigned int.
>>>> > > > > Moreover, the executed instructions cost could be minimal
>>>> > > > > without potiential data type conversion.
>>>> > > > >
>>>> > > > > Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
>>>> > > > > ---
>>>> > > > >  kernel/time/tick-sched.h | 2 +-
>>>> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
>>>> > > > >
>>>> > > > > diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
>>>> > > > > index 6de959a..4d34309 100644
>>>> > > > > --- a/kernel/time/tick-sched.h
>>>> > > > > +++ b/kernel/time/tick-sched.h
>>>> > > > > @@ -48,8 +48,8 @@ struct tick_sched {
>>>> > > > >         unsigned long                   check_clocks;
>>>> > > > >         enum tick_nohz_mode             nohz_mode;
>>>> > > > >
>>>> > > > > +       bool                            tick_stopped    : 1;
>>>> > > > >         unsigned int                    inidle          : 1;
>>>> > > > > -       unsigned int                    tick_stopped    : 1;
>>>> > > > >         unsigned int                    idle_active     : 1;
>>>> > > > >         unsigned int                    do_timer_last   : 1;
>>>> > > > >         unsigned int                    got_idle_tick   : 1;
>>>> > > >
>>>> > > > I don't think this is a good idea at all.
>>>> > > >
>>>> > > > Please see https://lkml.org/lkml/2017/11/21/384 for example.
>>>> > > [ZJ] Thanks for this sharing. Looks like, this patch fall into the case of
>>>> > > "Maybe".
>>>> >
>>>> > This patch falls into the case 'pointless' because it adds extra storage
>>>> [ZJ] 1 bit vs 1 bit. no more.
>>> 
>>> Groan. No. Care to look at the data structure? You create a new 
>>> storage,
>> [ZJ] Say, {unsigned int, unsigned int, unsigned int, unsigned int,
>> unsigned int} becomes
>>           {bool        , unsigned int, unsigned int, unsigned int, 
>> unsigned int}
>> As specified by the rule No.10 at the section 6.7.2.1 of C99 TC2 as:
>> "If enough space remains, a bit-field that immediately follows another
>> bit-field in a
>> structure shall be packed into adjacent bits of the same unit." What
>> is the new storage so far?
>> 
>>> which is incidentally merged into the other bitfield by the compiler 
>>> at a
>>> different bit position, but there is no guarantee that a compiler 
>>> does
>>> that. It's free to use distinct storage for that bool based bit.
>> [ZJ] Per the rule No.10 at section 6.7.2.1 of C99 TC2 as:
>> " If insufficient space remains, whether  a  bit-field  that  does
>> not  fit  is  put  into
>> the  next  unit  or overlaps  adjacent  units  is 
>> implementation-defined."
>> So, implementation is never mind which type will be stored if any.
>> 
>>> >> > for no benefit at all.
>>>> [ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() which 
>>>> is bool.
>>>> The benefit is no any potiential type conversion could be minded.
>>> 
>>> A bit stays a bit. 'bool foo : 1;' or 'unsigned int foo : 1' has to 
>>> be
>>> evaluated as a bit. So there is a type conversion from BIT to bool 
>>> required
>>> because BIT != bool.
>> [ZJ] Per the rule No.9 at section 6.7.2.1 of C99 TC2 as:
>> "If  the  value  0  or  1  is  stored  into  a  nonzero-width
>> bit-field  of  types
>> _Bool, the value of the bit-field shall compare equal to the value 
>> stored."
>> Obviously, it is nothing related to type conversion actually.
>>> 
>>> By chance the evaluation can be done by evaluating the byte in which 
>>> the
>>> bit is placed just because the compiler knows that the remaining bits 
>>> are
>>> not used. There is no guarantee that this is done, it happens to be 
>>> true
>>> for a particular compiler.
>> [ZJ] Actually, such as GCC owe that kind of guarantee to be promised 
>> by ABI.
>>> 
>>> But that does not make it any more interesting. It just makes the 
>>> code
>>> harder to read and eventually leads to bigger storage.
>> [ZJ] To get the benctifit to be profiled, it is given as:
>> number of instructions of function tick_nohz_tick_stopped():
> [ZJ] Here, I used is not the tick_nohz_tick_stopped(), but an 
> evaluation() as:
> #include <stdio.h>
> #include <stdbool.h>
> 
> struct tick_sched {
>         unsigned int inidle             : 1;
>         unsigned int tick_stopped       : 1;
> };
> 
> bool get_status()
> {
>         struct tick_sched *ts;
>         ts->tick_stopped = 1;
>         return ts->tick_stopped;
> }
> 
> int main()
> {
>         if (get_status()) return 0;
>         return 0;
> }
> 
> [ZJ] Toggle the declaration of tick_stopped in side of the tick_sched
> structure for comparison.
> 
> 
>>                         original: 17
>>                         patched:  14
>>      Which was saved is:
>>                movzbl	%al, %eax
>>                testl	%eax, %eax
>>                setne    %al
>>      Say, 3 / 17 = 17 % could be gained in the instruction executed
>> for this function can be evaluated.
>> 
>> Note:
>>      The environment I used is:
>>                OS : Ubuntu Desktop 16.04 LTS
>>                gcc: 6.3.0                       (without optimization
>> for in general purpose)
>> 
>>> 
> 
> Just FYI.
> 
> Thanks,
> ZJ
yuankuiz@codeaurora.org April 10, 2018, 11:20 p.m. UTC | #17
++
On 2018-04-11 07:09 AM, yuankuiz@codeaurora.org wrote:
> ++
> 
> On 2018-04-10 10:49 PM, yuankuiz@codeaurora.org wrote:
>> Typo...
>> 
>> On 2018-04-10 10:08 PM, yuankuiz@codeaurora.org wrote:
>>> On 2018-04-10 07:06 PM, Thomas Gleixner wrote:
>>>> On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>>>> On 2018-04-10 05:10 PM, Thomas Gleixner wrote:
>>>>> > On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>>>> > > On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
>>>>> > > > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
>>>>> > > > > From: John Zhao <yuankuiz@codeaurora.org>
>>>>> > > > >
>>>>> > > > > Variable tick_stopped returned by tick_nohz_tick_stopped
>>>>> > > > > can have only true / false values. Since the return type
>>>>> > > > > of the tick_nohz_tick_stopped is also bool, variable
>>>>> > > > > tick_stopped nice to have data type as bool in place of unsigned int.
>>>>> > > > > Moreover, the executed instructions cost could be minimal
>>>>> > > > > without potiential data type conversion.
>>>>> > > > >
>>>>> > > > > Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
>>>>> > > > > ---
>>>>> > > > >  kernel/time/tick-sched.h | 2 +-
>>>>> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>> > > > >
>>>>> > > > > diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
>>>>> > > > > index 6de959a..4d34309 100644
>>>>> > > > > --- a/kernel/time/tick-sched.h
>>>>> > > > > +++ b/kernel/time/tick-sched.h
>>>>> > > > > @@ -48,8 +48,8 @@ struct tick_sched {
>>>>> > > > >         unsigned long                   check_clocks;
>>>>> > > > >         enum tick_nohz_mode             nohz_mode;
>>>>> > > > >
>>>>> > > > > +       bool                            tick_stopped    : 1;
>>>>> > > > >         unsigned int                    inidle          : 1;
>>>>> > > > > -       unsigned int                    tick_stopped    : 1;
>>>>> > > > >         unsigned int                    idle_active     : 1;
>>>>> > > > >         unsigned int                    do_timer_last   : 1;
>>>>> > > > >         unsigned int                    got_idle_tick   : 1;
>>>>> > > >
>>>>> > > > I don't think this is a good idea at all.
>>>>> > > >
>>>>> > > > Please see https://lkml.org/lkml/2017/11/21/384 for example.
>>>>> > > [ZJ] Thanks for this sharing. Looks like, this patch fall into the case of
>>>>> > > "Maybe".
>>>>> >
>>>>> > This patch falls into the case 'pointless' because it adds extra storage
>>>>> [ZJ] 1 bit vs 1 bit. no more.
>>>> 
>>>> Groan. No. Care to look at the data structure? You create a new 
>>>> storage,
>>> [ZJ] Say, {unsigned int, unsigned int, unsigned int, unsigned int,
>>> unsigned int} becomes
>>>           {bool        , unsigned int, unsigned int, unsigned int, 
>>> unsigned int}
>>> As specified by the rule No.10 at the section 6.7.2.1 of C99 TC2 as:
>>> "If enough space remains, a bit-field that immediately follows 
>>> another
>>> bit-field in a
>>> structure shall be packed into adjacent bits of the same unit." What
>>> is the new storage so far?
>>> 
>>>> which is incidentally merged into the other bitfield by the compiler 
>>>> at a
>>>> different bit position, but there is no guarantee that a compiler 
>>>> does
>>>> that. It's free to use distinct storage for that bool based bit.
>>> [ZJ] Per the rule No.10 at section 6.7.2.1 of C99 TC2 as:
>>> " If insufficient space remains, whether  a  bit-field  that  does
>>> not  fit  is  put  into
>>> the  next  unit  or overlaps  adjacent  units  is 
>>> implementation-defined."
>>> So, implementation is never mind which type will be stored if any.
>>> 
>>>> >> > for no benefit at all.
>>>>> [ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() which 
>>>>> is bool.
>>>>> The benefit is no any potiential type conversion could be minded.
>>>> 
>>>> A bit stays a bit. 'bool foo : 1;' or 'unsigned int foo : 1' has to 
>>>> be
>>>> evaluated as a bit. So there is a type conversion from BIT to bool 
>>>> required
>>>> because BIT != bool.
>>> [ZJ] Per the rule No.9 at section 6.7.2.1 of C99 TC2 as:
>>> "If  the  value  0  or  1  is  stored  into  a  nonzero-width
>>> bit-field  of  types
>>> _Bool, the value of the bit-field shall compare equal to the value 
>>> stored."
>>> Obviously, it is nothing related to type conversion actually.
>>>> 
>>>> By chance the evaluation can be done by evaluating the byte in which 
>>>> the
>>>> bit is placed just because the compiler knows that the remaining 
>>>> bits are
>>>> not used. There is no guarantee that this is done, it happens to be 
>>>> true
>>>> for a particular compiler.
>>> [ZJ] Actually, such as GCC owe that kind of guarantee to be promised 
>>> by ABI.
>>>> 
>>>> But that does not make it any more interesting. It just makes the 
>>>> code
>>>> harder to read and eventually leads to bigger storage.
>>> [ZJ] To get the benctifit to be profiled, it is given as:
>>> number of instructions of function tick_nohz_tick_stopped():
>> [ZJ] Here, I used is not the tick_nohz_tick_stopped(), but an 
>> evaluation() as:
>> #include <stdio.h>
>> #include <stdbool.h>
>> 
>> struct tick_sched {
>>         unsigned int inidle             : 1;
>>         unsigned int tick_stopped       : 1;
>> };
>> 
>> bool get_status()
>> {
>>         struct tick_sched *ts;
>>         ts->tick_stopped = 1;
>>         return ts->tick_stopped;
>> }
>> 
>> int main()
>> {
>>         if (get_status()) return 0;
>>         return 0;
>> }
>> 
>> [ZJ] Toggle the declaration of tick_stopped in side of the tick_sched
>> structure for comparison.
>> 
>> 
>>>                         original: 17
>>>                         patched:  14
>>>      Which was saved is:
>>>                movzbl	%al, %eax
>>>                testl	%eax, %eax
>>>                setne    %al
>>>      Say, 3 / 17 = 17 % could be gained in the instruction executed
>>> for this function can be evaluated.
>>> 
>>> Note:
>>>      The environment I used is:
>>>                OS : Ubuntu Desktop 16.04 LTS
>>>                gcc: 6.3.0                       (without optimization
>>> for in general purpose)
>>> 
>>>> 
>> 
>> Just FYI.
>> 
>> Thanks,
>> ZJ
yuankuiz@codeaurora.org April 20, 2018, 1:47 a.m. UTC | #18
On 2018-04-11 07:20 AM, yuankuiz@codeaurora.org wrote:
> ++
> On 2018-04-11 07:09 AM, yuankuiz@codeaurora.org wrote:
>> ++
>> 
>> On 2018-04-10 10:49 PM, yuankuiz@codeaurora.org wrote:
>>> Typo...
>>> 
>>> On 2018-04-10 10:08 PM, yuankuiz@codeaurora.org wrote:
>>>> On 2018-04-10 07:06 PM, Thomas Gleixner wrote:
>>>>> On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>>>>> On 2018-04-10 05:10 PM, Thomas Gleixner wrote:
>>>>>> > On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>>>>> > > On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
>>>>>> > > > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
>>>>>> > > > > From: John Zhao <yuankuiz@codeaurora.org>
>>>>>> > > > >
>>>>>> > > > > Variable tick_stopped returned by tick_nohz_tick_stopped
>>>>>> > > > > can have only true / false values. Since the return type
>>>>>> > > > > of the tick_nohz_tick_stopped is also bool, variable
>>>>>> > > > > tick_stopped nice to have data type as bool in place of unsigned int.
>>>>>> > > > > Moreover, the executed instructions cost could be minimal
>>>>>> > > > > without potiential data type conversion.
>>>>>> > > > >
>>>>>> > > > > Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
>>>>>> > > > > ---
>>>>>> > > > >  kernel/time/tick-sched.h | 2 +-
>>>>>> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>> > > > >
>>>>>> > > > > diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
>>>>>> > > > > index 6de959a..4d34309 100644
>>>>>> > > > > --- a/kernel/time/tick-sched.h
>>>>>> > > > > +++ b/kernel/time/tick-sched.h
>>>>>> > > > > @@ -48,8 +48,8 @@ struct tick_sched {
>>>>>> > > > >         unsigned long                   check_clocks;
>>>>>> > > > >         enum tick_nohz_mode             nohz_mode;
>>>>>> > > > >
>>>>>> > > > > +       bool                            tick_stopped    : 1;
>>>>>> > > > >         unsigned int                    inidle          : 1;
>>>>>> > > > > -       unsigned int                    tick_stopped    : 1;
>>>>>> > > > >         unsigned int                    idle_active     : 1;
>>>>>> > > > >         unsigned int                    do_timer_last   : 1;
>>>>>> > > > >         unsigned int                    got_idle_tick   : 1;
>>>>>> > > >
>>>>>> > > > I don't think this is a good idea at all.
>>>>>> > > >
>>>>>> > > > Please see https://lkml.org/lkml/2017/11/21/384 for example.
>>>>>> > > [ZJ] Thanks for this sharing. Looks like, this patch fall into the case of
>>>>>> > > "Maybe".
>>>>>> >
>>>>>> > This patch falls into the case 'pointless' because it adds extra storage
>>>>>> [ZJ] 1 bit vs 1 bit. no more.
>>>>> 
>>>>> Groan. No. Care to look at the data structure? You create a new 
>>>>> storage,
>>>> [ZJ] Say, {unsigned int, unsigned int, unsigned int, unsigned int,
>>>> unsigned int} becomes
>>>>           {bool        , unsigned int, unsigned int, unsigned int, 
>>>> unsigned int}
>>>> As specified by the rule No.10 at the section 6.7.2.1 of C99 TC2 as:
>>>> "If enough space remains, a bit-field that immediately follows 
>>>> another
>>>> bit-field in a
>>>> structure shall be packed into adjacent bits of the same unit." What
>>>> is the new storage so far?
[ZJ] Further prototyping has been given based on gcc for both of x86_64 
and armv8-a,
      unsigned int and bool share the same 4 bytes without the addtional 
storage for sure.
      Open this and welcome if any other difference behaviour could be 
captured.
>>>> 
>>>>> which is incidentally merged into the other bitfield by the 
>>>>> compiler at a
>>>>> different bit position, but there is no guarantee that a compiler 
>>>>> does
>>>>> that. It's free to use distinct storage for that bool based bit.
>>>> [ZJ] Per the rule No.10 at section 6.7.2.1 of C99 TC2 as:
>>>> " If insufficient space remains, whether  a  bit-field  that  does
>>>> not  fit  is  put  into
>>>> the  next  unit  or overlaps  adjacent  units  is 
>>>> implementation-defined."
>>>> So, implementation is never mind which type will be stored if any.
>>>> 
>>>>> >> > for no benefit at all.
>>>>>> [ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() 
>>>>>> which is bool.
>>>>>> The benefit is no any potiential type conversion could be minded.
>>>>> 
>>>>> A bit stays a bit. 'bool foo : 1;' or 'unsigned int foo : 1' has to 
>>>>> be
>>>>> evaluated as a bit. So there is a type conversion from BIT to bool 
>>>>> required
>>>>> because BIT != bool.
>>>> [ZJ] Per the rule No.9 at section 6.7.2.1 of C99 TC2 as:
>>>> "If  the  value  0  or  1  is  stored  into  a  nonzero-width
>>>> bit-field  of  types
>>>> _Bool, the value of the bit-field shall compare equal to the value 
>>>> stored."
>>>> Obviously, it is nothing related to type conversion actually.
>>>>> 
>>>>> By chance the evaluation can be done by evaluating the byte in 
>>>>> which the
>>>>> bit is placed just because the compiler knows that the remaining 
>>>>> bits are
>>>>> not used. There is no guarantee that this is done, it happens to be 
>>>>> true
>>>>> for a particular compiler.
>>>> [ZJ] Actually, such as GCC owe that kind of guarantee to be promised 
>>>> by ABI.
>>>>> 
>>>>> But that does not make it any more interesting. It just makes the 
>>>>> code
>>>>> harder to read and eventually leads to bigger storage.
>>>> [ZJ] To get the benctifit to be profiled, it is given as:
>>>> number of instructions of function tick_nohz_tick_stopped():
>>> [ZJ] Here, I used is not the tick_nohz_tick_stopped(), but an 
>>> evaluation() as:
>>> #include <stdio.h>
>>> #include <stdbool.h>
>>> 
>>> struct tick_sched {
>>>         unsigned int inidle             : 1;
>>>         unsigned int tick_stopped       : 1;
>>> };
>>> 
>>> bool get_status()
>>> {
>>>         struct tick_sched *ts;
>>>         ts->tick_stopped = 1;
>>>         return ts->tick_stopped;
>>> }
>>> 
>>> int main()
>>> {
>>>         if (get_status()) return 0;
>>>         return 0;
>>> }
>>> 
>>> [ZJ] Toggle the declaration of tick_stopped in side of the tick_sched
>>> structure for comparison.
>>> 
>>> 
>>>>                         original: 17
>>>>                         patched:  14
>>>>      Which was saved is:
>>>>                movzbl	%al, %eax
>>>>                testl	%eax, %eax
>>>>                setne    %al
>>>>      Say, 3 / 17 = 17 % could be gained in the instruction executed
>>>> for this function can be evaluated.
>>>> 
>>>> Note:
>>>>      The environment I used is:
>>>>                OS : Ubuntu Desktop 16.04 LTS
>>>>                gcc: 6.3.0                       (without 
>>>> optimization
>>>> for in general purpose)
>>>> 
>>>>> 
>>> 
>>> Just FYI.
>>> 
>>> Thanks,
>>> ZJ
yuankuiz@codeaurora.org April 20, 2018, 6:44 a.m. UTC | #19
On 2018-04-20 09:47 AM, yuankuiz@codeaurora.org wrote:
> On 2018-04-11 07:20 AM, yuankuiz@codeaurora.org wrote:
>> ++
>> On 2018-04-11 07:09 AM, yuankuiz@codeaurora.org wrote:
>>> ++
>>> 
>>> On 2018-04-10 10:49 PM, yuankuiz@codeaurora.org wrote:
>>>> Typo...
>>>> 
>>>> On 2018-04-10 10:08 PM, yuankuiz@codeaurora.org wrote:
>>>>> On 2018-04-10 07:06 PM, Thomas Gleixner wrote:
>>>>>> On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>>>>>> On 2018-04-10 05:10 PM, Thomas Gleixner wrote:
>>>>>>> > On Tue, 10 Apr 2018, yuankuiz@codeaurora.org wrote:
>>>>>>> > > On 2018-04-10 04:00 PM, Rafael J. Wysocki wrote:
>>>>>>> > > > On Tue, Apr 10, 2018 at 9:33 AM,  <yuankuiz@codeaurora.org> wrote:
>>>>>>> > > > > From: John Zhao <yuankuiz@codeaurora.org>
>>>>>>> > > > >
>>>>>>> > > > > Variable tick_stopped returned by tick_nohz_tick_stopped
>>>>>>> > > > > can have only true / false values. Since the return type
>>>>>>> > > > > of the tick_nohz_tick_stopped is also bool, variable
>>>>>>> > > > > tick_stopped nice to have data type as bool in place of unsigned int.
>>>>>>> > > > > Moreover, the executed instructions cost could be minimal
>>>>>>> > > > > without potiential data type conversion.
>>>>>>> > > > >
>>>>>>> > > > > Signed-off-by: John Zhao <yuankuiz@codeaurora.org>
>>>>>>> > > > > ---
>>>>>>> > > > >  kernel/time/tick-sched.h | 2 +-
>>>>>>> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
>>>>>>> > > > >
>>>>>>> > > > > diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
>>>>>>> > > > > index 6de959a..4d34309 100644
>>>>>>> > > > > --- a/kernel/time/tick-sched.h
>>>>>>> > > > > +++ b/kernel/time/tick-sched.h
>>>>>>> > > > > @@ -48,8 +48,8 @@ struct tick_sched {
>>>>>>> > > > >         unsigned long                   check_clocks;
>>>>>>> > > > >         enum tick_nohz_mode             nohz_mode;
>>>>>>> > > > >
>>>>>>> > > > > +       bool                            tick_stopped    : 1;
>>>>>>> > > > >         unsigned int                    inidle          : 1;
>>>>>>> > > > > -       unsigned int                    tick_stopped    : 1;
>>>>>>> > > > >         unsigned int                    idle_active     : 1;
>>>>>>> > > > >         unsigned int                    do_timer_last   : 1;
>>>>>>> > > > >         unsigned int                    got_idle_tick   : 1;
>>>>>>> > > >
>>>>>>> > > > I don't think this is a good idea at all.
>>>>>>> > > >
>>>>>>> > > > Please see https://lkml.org/lkml/2017/11/21/384 for example.
>>>>>>> > > [ZJ] Thanks for this sharing. Looks like, this patch fall into the case of
>>>>>>> > > "Maybe".
>>>>>>> >
>>>>>>> > This patch falls into the case 'pointless' because it adds extra storage
>>>>>>> [ZJ] 1 bit vs 1 bit. no more.
>>>>>> 
>>>>>> Groan. No. Care to look at the data structure? You create a new 
>>>>>> storage,
>>>>> [ZJ] Say, {unsigned int, unsigned int, unsigned int, unsigned int,
>>>>> unsigned int} becomes
>>>>>           {bool        , unsigned int, unsigned int, unsigned int, 
>>>>> unsigned int}
>>>>> As specified by the rule No.10 at the section 6.7.2.1 of C99 TC2 
>>>>> as:
>>>>> "If enough space remains, a bit-field that immediately follows 
>>>>> another
>>>>> bit-field in a
>>>>> structure shall be packed into adjacent bits of the same unit." 
>>>>> What
>>>>> is the new storage so far?
> [ZJ] Further prototyping has been given based on gcc for both of
> x86_64 and armv8-a,
>      unsigned int and bool share the same 1 bytes without the
> addtional storage for sure.
>      Open this and welcome if any other difference behaviour could be 
> captured.
[ZJ] Typo.. change 4 bytes above to 1 byte actually.
>>>>> 
>>>>>> which is incidentally merged into the other bitfield by the 
>>>>>> compiler at a
>>>>>> different bit position, but there is no guarantee that a compiler 
>>>>>> does
>>>>>> that. It's free to use distinct storage for that bool based bit.
>>>>> [ZJ] Per the rule No.10 at section 6.7.2.1 of C99 TC2 as:
>>>>> " If insufficient space remains, whether  a  bit-field  that  does
>>>>> not  fit  is  put  into
>>>>> the  next  unit  or overlaps  adjacent  units  is 
>>>>> implementation-defined."
>>>>> So, implementation is never mind which type will be stored if any.
>>>>> 
>>>>>> >> > for no benefit at all.
>>>>>>> [ZJ] tick_stopped is returned by the tick_nohz_tick_stopped() 
>>>>>>> which is bool.
>>>>>>> The benefit is no any potiential type conversion could be minded.
>>>>>> 
>>>>>> A bit stays a bit. 'bool foo : 1;' or 'unsigned int foo : 1' has 
>>>>>> to be
>>>>>> evaluated as a bit. So there is a type conversion from BIT to bool 
>>>>>> required
>>>>>> because BIT != bool.
>>>>> [ZJ] Per the rule No.9 at section 6.7.2.1 of C99 TC2 as:
>>>>> "If  the  value  0  or  1  is  stored  into  a  nonzero-width
>>>>> bit-field  of  types
>>>>> _Bool, the value of the bit-field shall compare equal to the value 
>>>>> stored."
>>>>> Obviously, it is nothing related to type conversion actually.
>>>>>> 
>>>>>> By chance the evaluation can be done by evaluating the byte in 
>>>>>> which the
>>>>>> bit is placed just because the compiler knows that the remaining 
>>>>>> bits are
>>>>>> not used. There is no guarantee that this is done, it happens to 
>>>>>> be true
>>>>>> for a particular compiler.
>>>>> [ZJ] Actually, such as GCC owe that kind of guarantee to be 
>>>>> promised by ABI.
[ZJ] "-mone-byte-bool" could be used by alpha-linux-gcc to override the 
default bool size
      to become 1 byte for even Darwin / powerPC from it's manual.
>>>>>> 
>>>>>> But that does not make it any more interesting. It just makes the 
>>>>>> code
>>>>>> harder to read and eventually leads to bigger storage.
>>>>> [ZJ] To get the benctifit to be profiled, it is given as:
>>>>> number of instructions of function tick_nohz_tick_stopped():
>>>> [ZJ] Here, I used is not the tick_nohz_tick_stopped(), but an 
>>>> evaluation() as:
>>>> #include <stdio.h>
>>>> #include <stdbool.h>
>>>> 
>>>> struct tick_sched {
>>>>         unsigned int inidle             : 1;
>>>>         unsigned int tick_stopped       : 1;
>>>> };
>>>> 
>>>> bool get_status()
>>>> {
>>>>         struct tick_sched *ts;
>>>>         ts->tick_stopped = 1;
>>>>         return ts->tick_stopped;
>>>> }
>>>> 
>>>> int main()
>>>> {
>>>>         if (get_status()) return 0;
>>>>         return 0;
>>>> }
>>>> 
>>>> [ZJ] Toggle the declaration of tick_stopped in side of the 
>>>> tick_sched
>>>> structure for comparison.
>>>> 
>>>> 
>>>>>                         original: 17
>>>>>                         patched:  14
>>>>>      Which was saved is:
>>>>>                movzbl	%al, %eax
>>>>>                testl	%eax, %eax
>>>>>                setne    %al
>>>>>      Say, 3 / 17 = 17 % could be gained in the instruction executed
>>>>> for this function can be evaluated.
>>>>> 
>>>>> Note:
>>>>>      The environment I used is:
>>>>>                OS : Ubuntu Desktop 16.04 LTS
>>>>>                gcc: 6.3.0                       (without 
>>>>> optimization
>>>>> for in general purpose)
>>>>> 
>>>>>> 
>>>> 
>>>> Just FYI.
>>>> 
>>>> Thanks,
>>>> ZJ
Joe Perches April 20, 2018, 7:24 p.m. UTC | #20
On Fri, 2018-04-20 at 14:44 +0800, yuankuiz@codeaurora.org wrote:
> On 2018-04-20 09:47 AM, yuankuiz@codeaurora.org wrote:
[]
> > [ZJ] Further prototyping has been given based on gcc for both of
> > x86_64 and armv8-a,
> >      unsigned int and bool share the same 1 bytes without the
> > addtional storage for sure.
> >      Open this and welcome if any other difference behaviour could be 
> > captured.
> 
> [ZJ] Typo.. change 4 bytes above to 1 byte actually.

Not really.

unsigned int is 4 and bool is generally 1.
Alignment padding after a bool may exist.
yuankuiz@codeaurora.org April 25, 2018, 7:01 a.m. UTC | #21
On 2018-04-21 03:24 AM, Joe Perches wrote:
> On Fri, 2018-04-20 at 14:44 +0800, yuankuiz@codeaurora.org wrote:
>> On 2018-04-20 09:47 AM, yuankuiz@codeaurora.org wrote:
> []
>> > [ZJ] Further prototyping has been given based on gcc for both of
>> > x86_64 and armv8-a,
>> >      unsigned int and bool share the same 1 bytes without the
>> > addtional storage for sure.
>> >      Open this and welcome if any other difference behaviour could be
>> > captured.
>> 
>> [ZJ] Typo.. change 4 bytes above to 1 byte actually.
> 
> Not really.
> 
> unsigned int is 4 and bool is generally 1.
> Alignment padding after a bool may exist.
[ZJ] Depending on how to pack, the size was padded is variance. For 
example.
      In case of the "unsigned char" at the following, pack is happened 
and result 1 bytes.(if no more than 8 bits are used)
      In case of the "int" at the following, pack is happened but result 
4 bytes.
      I mean, I demo it but use the 1# case due for another thread 
discussion on the ichx_desc() so move a little bit from the tick_sched 
struct.
diff mbox

Patch

diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
index 6de959a..4d34309 100644
--- a/kernel/time/tick-sched.h
+++ b/kernel/time/tick-sched.h
@@ -48,8 +48,8 @@  struct tick_sched {
  	unsigned long			check_clocks;
  	enum tick_nohz_mode		nohz_mode;

+	bool				tick_stopped	: 1;
  	unsigned int			inidle		: 1;
-	unsigned int			tick_stopped	: 1;
  	unsigned int			idle_active	: 1;
  	unsigned int			do_timer_last	: 1;
  	unsigned int			got_idle_tick	: 1;