All of lore.kernel.org
 help / color / mirror / Atom feed
From: Akira Yokosawa <akiyks@gmail.com>
To: "Paul E. McKenney" <paulmck@linux.ibm.com>
Cc: perfbook@vger.kernel.org, Akira Yokosawa <akiyks@gmail.com>
Subject: Re: [PATCH 2/2] count: Adjust type of variable 'counter' with code snippet
Date: Wed, 3 Oct 2018 07:12:32 +0900	[thread overview]
Message-ID: <67a1d644-6289-4582-aa1b-d8f97bf4b538@gmail.com> (raw)
In-Reply-To: <20181002182123.GK4222@linux.ibm.com>

On 2018/10/02 11:21:23 -0700, Paul E. McKenney wrote:
> On Wed, Oct 03, 2018 at 12:24:17AM +0900, Akira Yokosawa wrote:
>> On 2018/10/03 00:16:12 +0900, Akira Yokosawa wrote:
>>> From a9c276c3da87ed327d003a70d60777f41999b4fc Mon Sep 17 00:00:00 2001
>>> From: Akira Yokosawa <akiyks@gmail.com>
>>> Date: Wed, 3 Oct 2018 00:08:49 +0900
>>> Subject: [PATCH 2/2] count: Adjust type of variable 'counter' with code snippet
>>>
>>> In the actual code of count_stat.c, the per-thread variable
>>> "counter" has the type "unsigned long".
> 
> Looks good, so I applied and pushed both patches, thank you!
> 
>> And the other description on Listing 5.3 in the text needs some reworking
>> to reflect the changes in the snippet. Paul, can you have a look into
>> this?
> 
> How does the patch below look?

Looks good to me (at least for the moment).

Acked-by: Akira Yokosawa <akiyks@gmail.com>

And I'm anticipating your expansion on the use of READ_ONCE()/WRITE_ONCE()
in, say, somewhere in toolsoftrade. Then we would be able to reduce
repetitive explanation here and there.

I'll continue to apply new scheme for other snippets in "count" chapter.

        Thanks, Akira

> 
> 							Thanx, Paul
> 
> ------------------------------------------------------------------------
> 
> commit cc0409cfb0581924b05744a15fa3ebd5c1e298af
> Author: Paul E. McKenney <paulmck@linux.ibm.com>
> Date:   Tue Oct 2 11:19:33 2018 -0700
> 
>     count: Update code description and QQ based on {READ,WRITE}_ONCE()
>     
>     Reported-by: Akira Yokosawa <akiyks@gmail.com>
>     Signed-off-by: Paul E. McKenney <paulmck@linux.ibm.com>
> 
> diff --git a/count/count.tex b/count/count.tex
> index 9f9fd0f64838..c36e7d826a7b 100644
> --- a/count/count.tex
> +++ b/count/count.tex
> @@ -495,23 +495,22 @@ show a function that increments the counters, using the
>  thread's element of the \co{counter} array.
>  Because this element is modified only by the corresponding thread,
>  non-atomic increment suffices.
> -
> -Lines~\lnref{read:b}-\lnref{read:e}
> -show a function that reads out the aggregate value of the counter,
> -using the \co{for_each_thread()} primitive to iterate over the list of
> -currently running threads, and using the \co{per_thread()} primitive
> -to fetch the specified thread's counter.
> -Because the hardware can fetch and store a properly aligned \co{unsigned long}
> -atomically, and because \GCC\ is kind enough to make use of this capability,
> -normal loads suffice, and no special atomic instructions are required.
> -\end{lineref}
> +However, this code uses \co{WRITE_ONCE()} to prevent destructive compiler
> +optimizations.
> +For but one example, the compiler is within its rights to use a
> +to-be-stored-to location as temporary storage, thus writing what
> +would be for all intents and purposes garbage to that location
> +just before doing the desired store.
> +This could of course be rather confusing to anything attempting to
> +read out the count.
> +The use of \co{WRITE_ONCE()} prevents this optimization and others besides.
>  
>  \QuickQuiz{}
> -	What other choice does \GCC\ have, anyway???
> +	What other nasty optimizations could \GCC\ apply?
>  \QuickQuizAnswer{
> -	According to the C standard, the effects of fetching a variable
> -	that might be concurrently modified by some other thread are
> -	undefined.
> +	According to the C standard, the effects of doing a normal store
> +	to a variable that might be concurrently loaded by some other
> +	thread are undefined.
>  	It turns out that the C standard really has no other choice,
>  	given that C must support (for example) eight-bit architectures
>  	which are incapable of atomically loading a \co{long}.
> @@ -540,8 +539,10 @@ normal loads suffice, and no special atomic instructions are required.
>  	It is therefore reasonable to expect that any Linux-kernel
>  	adoption of C11 atomics will be incremental at best.
>  
> -	So why not just use plain old C-language assignment statements
> -	to access shared variables?
> +	But if the code is doing loads and stores that the underlying
> +	hardware can implement with single instructions, why not just
> +	use plain old C-language assignment statements to access shared
> +	variables?
>  	The problem is that the compiler is within its rights to assume
>  	that no other thread is modifying the variable being accessed.
>  	Given a plain old C-language load, the compiler would therefore
> @@ -581,6 +582,22 @@ normal loads suffice, and no special atomic instructions are required.
>  	coding standards.
>  } \QuickQuizEnd
>  
> +Lines~\lnref{read:b}-\lnref{read:e}
> +show a function that reads out the aggregate value of the counter,
> +using the \co{for_each_thread()} primitive to iterate over the list of
> +currently running threads, and using the \co{per_thread()} primitive
> +to fetch the specified thread's counter.
> +This code also uses \co{READ_ONCE()} to ensure that the compiler doesn't
> +optimize these loads into oblivion.
> +For but one example, a pair of consecutive calls to \co{read_count()}
> +might be inlined, and an intrepid optimizer might notice that the same
> +locations were being summed and thus incorrectly conclude that it would
> +be simply wonderful to sum them once and use the resulting value twice.
> +This sort of optimization might be rather frustrating to people expecting
> +later \co{read_count()} calls to return larger values.
> +The use of \co{READ_ONCE()} prevents this optimization and others besides.
> +\end{lineref}
> +
>  \QuickQuiz{}
>  	How does the per-thread \co{counter} variable in
>  	Listing~\ref{lst:count:Array-Based Per-Thread Statistical Counters}
> 


  reply	other threads:[~2018-10-02 22:12 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-02 15:15 [PATCH 1/2] count: Employ new scheme for snippet from count_stat.c Akira Yokosawa
2018-10-02 15:16 ` [PATCH 2/2] count: Adjust type of variable 'counter' with code snippet Akira Yokosawa
2018-10-02 15:24   ` Akira Yokosawa
2018-10-02 18:21     ` Paul E. McKenney
2018-10-02 22:12       ` Akira Yokosawa [this message]
2018-10-04  3:40         ` Paul E. McKenney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=67a1d644-6289-4582-aa1b-d8f97bf4b538@gmail.com \
    --to=akiyks@gmail.com \
    --cc=paulmck@linux.ibm.com \
    --cc=perfbook@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.