All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] toolsoftrade: Employ new scheme for snippet in newly added sections
@ 2018-10-05 15:38 Akira Yokosawa
  2018-10-05 20:56 ` Paul E. McKenney
  0 siblings, 1 reply; 2+ messages in thread
From: Akira Yokosawa @ 2018-10-05 15:38 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

From 89be258c86a41713c327995d8ed46c12c3fba736 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@gmail.com>
Date: Sat, 6 Oct 2018 00:11:04 +0900
Subject: [PATCH] toolsoftrade: Employ new scheme for snippet in newly added sections

These code snippets don't have corresponding code under CodeSamples.
Embed them in the "VerbatimL" environment with labels to lines 
referenced from the text.

A few trivial typos are fixed as well.

Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
---
Hi Paul,

I see you have used verbbox for new code snippets. VerbatimL can be used
instead as shown in this patch. Hopefully this can provide a few
templates for you to use the new scheme without putting actual code
under CodeSamples. In these snippets, labelbase has the same string as
the listing's label, give or take the leading prefix ("lst:" -> "ln:").

If you don't feel like using the new scheme for the moment, I'd be happy
to do the conversion on behalf of you.

BTW, the expansion on accessing shared variable makes a lot of sense
to me. I'm a bit afraid of possible conflict with your ongoing expansion
in toolsoftrade, but I thought it is better rather than later.

        Thanks, Akira
--
 toolsoftrade/toolsoftrade.tex | 224 ++++++++++++++++++++++--------------------
 1 file changed, 117 insertions(+), 107 deletions(-)

diff --git a/toolsoftrade/toolsoftrade.tex b/toolsoftrade/toolsoftrade.tex
index 53c69b2..5216054 100644
--- a/toolsoftrade/toolsoftrade.tex
+++ b/toolsoftrade/toolsoftrade.tex
@@ -1661,29 +1661,25 @@ in long-past pre-C11 days.
 A short answer to this question is ``they lived dangerously''.
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
- 1 ptr = global_ptr;
- 2 if (ptr != NULL && ptr < high_address)
- 3   do_low(ptr);
-\end{verbbox}
-}
-\centering
-\theverbbox
+\begin{linelabel}[ln:toolsoftrade:Living Dangerously Early 1990s Style]
+\begin{VerbatimL}[commandchars=\\\{\}]
+ptr = global_ptr;\lnlbl{temp}
+if (ptr != NULL && ptr < high_address)
+	do_low(ptr);
+\end{VerbatimL}
+\end{linelabel}
 \caption{Living Dangerously Early 1990s Style}
 \label{lst:toolsoftrade:Living Dangerously Early 1990s Style}
 \end{listing}
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
- 1 if (global_ptr != NULL &&
- 2     global_ptr < high_address)
- 3   do_low(global_ptr);
-\end{verbbox}
-}
-\centering
-\theverbbox
+\begin{linelabel}[ln:toolsoftrade:C Compilers Can Invent Loads]
+\begin{VerbatimL}[commandchars=\\\{\}]
+if (global_ptr != NULL &&\lnlbl{if:a}
+    global_ptr < high_address)\lnlbl{if:b}
+	do_low(global_ptr);\lnlbl{do_low}
+\end{VerbatimL}
+\end{linelabel}
 \caption{C Compilers Can Invent Loads}
 \label{lst:toolsoftrade:C Compilers Can Invent Loads}
 \end{listing}
@@ -1696,7 +1692,8 @@ Nevertheless, problems did arise, as shown in
 Listing~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style},
 which the compiler is within its rights to transform into
 Listing~\ref{lst:toolsoftrade:C Compilers Can Invent Loads}.
-As you can, the temporary on line~1 of
+As you can, the temporary on
+line~\ref{ln:toolsoftrade:Living Dangerously Early 1990s Style:temp} of
 Listing~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style}
 has been optimized away, so that \co{global_ptr} will been loaded
 up to three times.
@@ -1708,14 +1705,18 @@ up to three times.
 \QuickQuizAnswer{
 	Suppose that \co{global_ptr} is initially non-\co{NULL},
 	but that some other thread sets \co{global_ptr} to \co{NULL}.
-	Suppose further that line~1 of the transformed code
+	\begin{lineref}[ln:toolsoftrade:C Compilers Can Invent Loads]
+	Suppose further that line~\lnref{if:a} of the transformed code
 	(Listing~\ref{lst:toolsoftrade:C Compilers Can Invent Loads})
 	executes just before \co{global_ptr} is set to \co{NULL} and
-	line~2 just after.
-	Then line~1 will conclude that \co{global_ptr} is non-\co{NULL},
-	line~2 will conclude that it is less than \co{high_address},
-	so that line~3 passes \co{do_low()} a \co{NULL} pointer,
+	line~\lnref{if:b} just after.
+	Then line~\lnref{if:a} will conclude that
+        \co{global_ptr} is non-\co{NULL},
+	line~\lnref{if:b} will conclude that it is less than
+        \co{high_address},
+	so that line~\lnref{do_low} passes \co{do_low()} a \co{NULL} pointer,
 	which \co{do_low()} just might not be prepared to deal with.
+	\end{lineref}
 } \QuickQuizEnd
 
 Section~\ref{sec:toolsoftrade:Shared-Variable Shenanigans}
@@ -1750,7 +1751,8 @@ or shared-variable shenanigans, as described below.
 {\bf Load tearing} occurs when the compiler uses multiple load
 instructions for a single access.
 For example, the compiler could in theory compile the load from
-\co{global_ptr} (see line~1 of
+\co{global_ptr} (see
+line~\ref{ln:toolsoftrade:Living Dangerously Early 1990s Style:temp} of
 Listing~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style})
 as a series of one-byte loads.
 If some other thread was concurrently setting \co{global_ptr} to
@@ -1776,31 +1778,29 @@ Again, the C standard simply has no choice in the general case, given
 the possibility of code using 32-bit integers running on a 16-bit system.
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
- 1 if (!need_to_stop)
- 2   for (;;) {
- 3     do_something_quickly();
- 4     do_something_quickly();
- 5     do_something_quickly();
- 6     do_something_quickly();
- 7     do_something_quickly();
- 8     do_something_quickly();
- 9     do_something_quickly();
-10     do_something_quickly();
-11     do_something_quickly();
-12     do_something_quickly();
-13     do_something_quickly();
-14     do_something_quickly();
-15     do_something_quickly();
-16     do_something_quickly();
-17     do_something_quickly();
-18     do_something_quickly();
-19   }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\begin{linelabel}[ln:toolsoftrade:C Compilers Can Fuse Loads]
+\begin{VerbatimL}[commandchars=\\\[\]]
+if (!need_to_stop)
+	for (;;) {\lnlbl[loop:b]
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+		do_something_quickly();
+	}\lnlbl[loop:e]
+\end{VerbatimL}
+\end{linelabel}
 \caption{C Compilers Can Fuse Loads}
 \label{lst:toolsoftrade:C Compilers Can Fuse Loads}
 \end{listing}
@@ -1822,8 +1822,11 @@ Worse yet, because the compiler knows that \co{do_something_quickly()}
 does not store to \co{need_to_stop}, the compiler could quite reasonably
 decide to check this variable only once, resulting in the code shown in
 Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Loads}.
-Once entered, the loop on lines~2-19 will never stop, regardless of how
+\begin{lineref}[ln:toolsoftrade:C Compilers Can Fuse Loads]
+Once entered, the loop on
+lines~\lnref{loop:b}-\lnref{loop:e} will never stop, regardless of how
 many times some other thread stores a non-zero value to \co{need_to_stop}.
+\end{lineref}
 The result will at best be disappointment, and might well also
 include severe physical damage.
 
@@ -1837,46 +1840,48 @@ very little chance that some other thread could load the value from the
 first store.
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
- 1 void shut_it_down(void)
- 2 {
- 3   status = SHUTTING_DOWN; /* BUGGY!!! */
- 4   start_shutdown();
- 5   while (!other_task_ready)
- 6     continue;
- 7   finish_shutdown();
- 8   status = SHUT_DOWN;
- 9   do_something_else();
-10 }
-11
-12 void work_until_shut_down(void)
-13 {
-14   while (status != SHUTTING_DOWN)
-15     do_more_work();
-16   other_task_ready = 1; /* BUGGY!!! */
-17 }
-\end{verbbox}
+\begin{linelabel}[ln:toolsoftrade:C Compilers Can Fuse Stores]
+\begin{VerbatimL}[commandchars=\\\[\]]
+void shut_it_down(void)
+{
+	status = SHUTTING_DOWN; /* BUGGY!!! */\lnlbl[store:a]
+	start_shutdown();
+	while (!other_task_ready)\lnlbl[loop:b]
+		continue;\lnlbl[loop:e]
+	finish_shutdown();\lnlbl[finish]
+	status = SHUT_DOWN;\lnlbl[store:b]
+	do_something_else();
 }
-\centering
-\theverbbox
+
+void work_until_shut_down(void)
+{
+	while (status != SHUTTING_DOWN)\lnlbl[until:loop:b]
+		do_more_work();\lnlbl[until:loop:e]
+	other_task_ready = 1; /* BUGGY!!! */\lnlbl[other:store]
+}
+\end{VerbatimL}
+\end{linelabel}
 \caption{C Compilers Can Fuse Stores}
 \label{lst:toolsoftrade:C Compilers Can Fuse Stores}
 \end{listing}
 
 However, there are exceptions, for example as shown in
 Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Stores}.
+\begin{lineref}[ln:toolsoftrade:C Compilers Can Fuse Stores]
 The function \co{shut_it_down(void)()} stores to the shared
-variable \co{status} on lines~3 and~8, and so assuming that neither
+variable \co{status} on lines~\lnref{store:a} and~\lnref{store:b},
+and so assuming that neither
 \co{start_shutdown()} nor \co{finish_shutdown()} access \co{status},
 the compiler could reasonably remove the store to \co{status} on
-line~3.
+line~\lnref{store:a}.
 Unfortunately, this would mean that \co{work_until_shut_down()} would
-never exit its loop spanning lines~14 and~15, and thus would never set
+never exit its loop spanning
+lines~\lnref{until:loop:b} and~\lnref{until:loop:e}, and thus would never set
 \co{other_task_ready}, which would in turn mean that \co{shut_it_down()}
-would never exit its loop spanning lines~5 and~6, even if
+would never exit its loop spanning
+lines~\lnref{loop:b} and~\lnref{loop:e}, even if
 the compiler chooses not to fuse the successive loads from
-\co{(!other_task_ready} on line~5.
+\co{(!other_task_ready)} on line~\lnref{loop:b}.
 
 And there are more problems with the code in
 Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Stores},
@@ -1889,16 +1894,19 @@ modern superscalar microprocessors.
 It is also another reason why the code in
 Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Stores}
 is buggy.
-For example, suppose that the \co{do_more_work()} function on line~15
+For example, suppose that the \co{do_more_work()} function on
+line~\lnref{until:loop:e}
 does not access \co{other_task_ready}.
 Then the compiler would be within its rights to move the assignment
-to \co{other_task_ready} on line~16 to precede line~14, which might
+to \co{other_task_ready} on
+line~\lnref{other:store} to precede line~\lnref{until:loop:b}, which might
 be a great disappointment for anyone hoping that the last call to
-\co{do_more_work()} on line~15 happens before the call to
-\co{finish_shutdown()} on line~7.
+\co{do_more_work()} on line~\lnref{until:loop:e} happens before the call to
+\co{finish_shutdown()} on line~\lnref{finish}.
+\end{lineref}
 
 {\bf Invented loads} were illustrated by the code in
-Listings~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style})
+Listings~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style}
 and~\ref{lst:toolsoftrade:C Compilers Can Invent Loads},
 in which the compiler optimized away a temporary variable,
 thus loading from a shared variable more often than intended.
@@ -1910,50 +1918,49 @@ These hoisting optimizations are not uncommon, and can cause significant
 increases in cache misses, and thus significant degradation of
 both performance and scalability.
 
+\begin{lineref}[ln:toolsoftrade:C Compilers Can Fuse Stores]
 {\bf Invented stores} can occur in a number of situations.
 For example, a compiler emitting code for \co{work_until_shut_down()} in
 Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Stores}
 might notice that \co{other_task_ready} is not accessed by
-\co{do_more_work()}, and stored to on line~16.
+\co{do_more_work()}, and stored to on line~\lnref{other:store}.
 If \co{do_more_work()} was a complex inline function, it might be
 necessary to do a register spill, in which case one attractive
 place to use for temporary storage is \co{other_task_ready}.
 After all, there are no accesses to it, so what is the harm?
 
 Of course, a non-zero store to this variable at just the wrong time
-would result in the \co{while} loop on line~5 terminating
+would result in the \co{while} loop on
+line~\lnref{loop:b} terminating
 prematurely, again allowing \co{finish_shutdown()} to run
 concurrently with \co{do_more_work()}.
 Given that the entire point of this \co{while} appears to be to
 prevent such concurrency, this is not a good thing.
+\end{lineref}
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
- 1 if (condition)
- 2   a = 1;
- 3 else
- 4   do_a_bunch_of_stuff();
-\end{verbbox}
-}
-\centering
-\theverbbox
+\begin{linelabel}[ln:toolsoftrade:Inviting an Invented Store]
+\begin{VerbatimL}[commandchars=\\\{\}]
+if (condition)
+	a = 1;
+else
+	do_a_bunch_of_stuff();
+\end{VerbatimL}
+\end{linelabel}
 \caption{Inviting an Invented Store}
 \label{lst:toolsoftrade:Inviting an Invented Store}
 \end{listing}
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
- 1 a = 1;
- 2 if (!condition) {
- 3   a = 0;
- 4   do_a_bunch_of_stuff();
- 5 }
-\end{verbbox}
+\begin{linelabel}[ln:toolsoftrade:Compiler Invents an Invited Store]
+\begin{VerbatimL}[commandchars=\\\[\]]
+a = 1;\lnlbl[store:uncond]
+if (!condition) {
+	a = 0;\lnlbl[store:cond]
+	do_a_bunch_of_stuff();
 }
-\centering
-\theverbbox
+\end{VerbatimL}
+\end{linelabel}
 \caption{Compiler Invents an Invited Store}
 \label{lst:toolsoftrade:Compiler Invents an Invited Store}
 \end{listing}
@@ -1971,9 +1978,12 @@ might know that the value of \co{a} is initially zero,
 which might be a strong temptation to optimize away one branch
 by transforming this code to that in
 Listing~\ref{lst:toolsoftrade:Compiler Invents an Invited Store}.
-Here, line~1 unconditionally stores \co{1} to \co{1}, then
-resets the value back to zero on line~3 if \co{condition} was not set.
+\begin{lineref}[ln:toolsoftrade:Compiler Invents an Invited Store]
+Here, line~\lnref{store:uncond} unconditionally stores \co{1} to \co{a}, then
+resets the value back to zero on
+line~\lnref{store:cond} if \co{condition} was not set.
 This transforms the if-then-else into an if-then, saving one branch.
+\end{lineref}
 
 Finally, pre-C11 compilers could invent writes to unrelated
 variables that happened to be adjacent to written-to
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] toolsoftrade: Employ new scheme for snippet in newly added sections
  2018-10-05 15:38 [PATCH] toolsoftrade: Employ new scheme for snippet in newly added sections Akira Yokosawa
@ 2018-10-05 20:56 ` Paul E. McKenney
  0 siblings, 0 replies; 2+ messages in thread
From: Paul E. McKenney @ 2018-10-05 20:56 UTC (permalink / raw)
  To: Akira Yokosawa; +Cc: perfbook

On Sat, Oct 06, 2018 at 12:38:49AM +0900, Akira Yokosawa wrote:
> >From 89be258c86a41713c327995d8ed46c12c3fba736 Mon Sep 17 00:00:00 2001
> From: Akira Yokosawa <akiyks@gmail.com>
> Date: Sat, 6 Oct 2018 00:11:04 +0900
> Subject: [PATCH] toolsoftrade: Employ new scheme for snippet in newly added sections
> 
> These code snippets don't have corresponding code under CodeSamples.
> Embed them in the "VerbatimL" environment with labels to lines 
> referenced from the text.
> 
> A few trivial typos are fixed as well.
> 
> Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
> ---
> Hi Paul,
> 
> I see you have used verbbox for new code snippets. VerbatimL can be used
> instead as shown in this patch. Hopefully this can provide a few
> templates for you to use the new scheme without putting actual code
> under CodeSamples. In these snippets, labelbase has the same string as
> the listing's label, give or take the leading prefix ("lst:" -> "ln:").
> 
> If you don't feel like using the new scheme for the moment, I'd be happy
> to do the conversion on behalf of you.
> 
> BTW, the expansion on accessing shared variable makes a lot of sense
> to me. I'm a bit afraid of possible conflict with your ongoing expansion
> in toolsoftrade, but I thought it is better rather than later.

Good catch, applied and queued, thank you!

What can I say?  Force of habit and all that.  But I have nearby
examples now, at least.  ;-)

							Thanx, Paul

>         Thanks, Akira
> --
>  toolsoftrade/toolsoftrade.tex | 224 ++++++++++++++++++++++--------------------
>  1 file changed, 117 insertions(+), 107 deletions(-)
> 
> diff --git a/toolsoftrade/toolsoftrade.tex b/toolsoftrade/toolsoftrade.tex
> index 53c69b2..5216054 100644
> --- a/toolsoftrade/toolsoftrade.tex
> +++ b/toolsoftrade/toolsoftrade.tex
> @@ -1661,29 +1661,25 @@ in long-past pre-C11 days.
>  A short answer to this question is ``they lived dangerously''.
>  
>  \begin{listing}[tbp]
> -{ \scriptsize
> -\begin{verbbox}
> - 1 ptr = global_ptr;
> - 2 if (ptr != NULL && ptr < high_address)
> - 3   do_low(ptr);
> -\end{verbbox}
> -}
> -\centering
> -\theverbbox
> +\begin{linelabel}[ln:toolsoftrade:Living Dangerously Early 1990s Style]
> +\begin{VerbatimL}[commandchars=\\\{\}]
> +ptr = global_ptr;\lnlbl{temp}
> +if (ptr != NULL && ptr < high_address)
> +	do_low(ptr);
> +\end{VerbatimL}
> +\end{linelabel}
>  \caption{Living Dangerously Early 1990s Style}
>  \label{lst:toolsoftrade:Living Dangerously Early 1990s Style}
>  \end{listing}
>  
>  \begin{listing}[tbp]
> -{ \scriptsize
> -\begin{verbbox}
> - 1 if (global_ptr != NULL &&
> - 2     global_ptr < high_address)
> - 3   do_low(global_ptr);
> -\end{verbbox}
> -}
> -\centering
> -\theverbbox
> +\begin{linelabel}[ln:toolsoftrade:C Compilers Can Invent Loads]
> +\begin{VerbatimL}[commandchars=\\\{\}]
> +if (global_ptr != NULL &&\lnlbl{if:a}
> +    global_ptr < high_address)\lnlbl{if:b}
> +	do_low(global_ptr);\lnlbl{do_low}
> +\end{VerbatimL}
> +\end{linelabel}
>  \caption{C Compilers Can Invent Loads}
>  \label{lst:toolsoftrade:C Compilers Can Invent Loads}
>  \end{listing}
> @@ -1696,7 +1692,8 @@ Nevertheless, problems did arise, as shown in
>  Listing~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style},
>  which the compiler is within its rights to transform into
>  Listing~\ref{lst:toolsoftrade:C Compilers Can Invent Loads}.
> -As you can, the temporary on line~1 of
> +As you can, the temporary on
> +line~\ref{ln:toolsoftrade:Living Dangerously Early 1990s Style:temp} of
>  Listing~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style}
>  has been optimized away, so that \co{global_ptr} will been loaded
>  up to three times.
> @@ -1708,14 +1705,18 @@ up to three times.
>  \QuickQuizAnswer{
>  	Suppose that \co{global_ptr} is initially non-\co{NULL},
>  	but that some other thread sets \co{global_ptr} to \co{NULL}.
> -	Suppose further that line~1 of the transformed code
> +	\begin{lineref}[ln:toolsoftrade:C Compilers Can Invent Loads]
> +	Suppose further that line~\lnref{if:a} of the transformed code
>  	(Listing~\ref{lst:toolsoftrade:C Compilers Can Invent Loads})
>  	executes just before \co{global_ptr} is set to \co{NULL} and
> -	line~2 just after.
> -	Then line~1 will conclude that \co{global_ptr} is non-\co{NULL},
> -	line~2 will conclude that it is less than \co{high_address},
> -	so that line~3 passes \co{do_low()} a \co{NULL} pointer,
> +	line~\lnref{if:b} just after.
> +	Then line~\lnref{if:a} will conclude that
> +        \co{global_ptr} is non-\co{NULL},
> +	line~\lnref{if:b} will conclude that it is less than
> +        \co{high_address},
> +	so that line~\lnref{do_low} passes \co{do_low()} a \co{NULL} pointer,
>  	which \co{do_low()} just might not be prepared to deal with.
> +	\end{lineref}
>  } \QuickQuizEnd
>  
>  Section~\ref{sec:toolsoftrade:Shared-Variable Shenanigans}
> @@ -1750,7 +1751,8 @@ or shared-variable shenanigans, as described below.
>  {\bf Load tearing} occurs when the compiler uses multiple load
>  instructions for a single access.
>  For example, the compiler could in theory compile the load from
> -\co{global_ptr} (see line~1 of
> +\co{global_ptr} (see
> +line~\ref{ln:toolsoftrade:Living Dangerously Early 1990s Style:temp} of
>  Listing~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style})
>  as a series of one-byte loads.
>  If some other thread was concurrently setting \co{global_ptr} to
> @@ -1776,31 +1778,29 @@ Again, the C standard simply has no choice in the general case, given
>  the possibility of code using 32-bit integers running on a 16-bit system.
>  
>  \begin{listing}[tbp]
> -{ \scriptsize
> -\begin{verbbox}
> - 1 if (!need_to_stop)
> - 2   for (;;) {
> - 3     do_something_quickly();
> - 4     do_something_quickly();
> - 5     do_something_quickly();
> - 6     do_something_quickly();
> - 7     do_something_quickly();
> - 8     do_something_quickly();
> - 9     do_something_quickly();
> -10     do_something_quickly();
> -11     do_something_quickly();
> -12     do_something_quickly();
> -13     do_something_quickly();
> -14     do_something_quickly();
> -15     do_something_quickly();
> -16     do_something_quickly();
> -17     do_something_quickly();
> -18     do_something_quickly();
> -19   }
> -\end{verbbox}
> -}
> -\centering
> -\theverbbox
> +\begin{linelabel}[ln:toolsoftrade:C Compilers Can Fuse Loads]
> +\begin{VerbatimL}[commandchars=\\\[\]]
> +if (!need_to_stop)
> +	for (;;) {\lnlbl[loop:b]
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +		do_something_quickly();
> +	}\lnlbl[loop:e]
> +\end{VerbatimL}
> +\end{linelabel}
>  \caption{C Compilers Can Fuse Loads}
>  \label{lst:toolsoftrade:C Compilers Can Fuse Loads}
>  \end{listing}
> @@ -1822,8 +1822,11 @@ Worse yet, because the compiler knows that \co{do_something_quickly()}
>  does not store to \co{need_to_stop}, the compiler could quite reasonably
>  decide to check this variable only once, resulting in the code shown in
>  Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Loads}.
> -Once entered, the loop on lines~2-19 will never stop, regardless of how
> +\begin{lineref}[ln:toolsoftrade:C Compilers Can Fuse Loads]
> +Once entered, the loop on
> +lines~\lnref{loop:b}-\lnref{loop:e} will never stop, regardless of how
>  many times some other thread stores a non-zero value to \co{need_to_stop}.
> +\end{lineref}
>  The result will at best be disappointment, and might well also
>  include severe physical damage.
>  
> @@ -1837,46 +1840,48 @@ very little chance that some other thread could load the value from the
>  first store.
>  
>  \begin{listing}[tbp]
> -{ \scriptsize
> -\begin{verbbox}
> - 1 void shut_it_down(void)
> - 2 {
> - 3   status = SHUTTING_DOWN; /* BUGGY!!! */
> - 4   start_shutdown();
> - 5   while (!other_task_ready)
> - 6     continue;
> - 7   finish_shutdown();
> - 8   status = SHUT_DOWN;
> - 9   do_something_else();
> -10 }
> -11
> -12 void work_until_shut_down(void)
> -13 {
> -14   while (status != SHUTTING_DOWN)
> -15     do_more_work();
> -16   other_task_ready = 1; /* BUGGY!!! */
> -17 }
> -\end{verbbox}
> +\begin{linelabel}[ln:toolsoftrade:C Compilers Can Fuse Stores]
> +\begin{VerbatimL}[commandchars=\\\[\]]
> +void shut_it_down(void)
> +{
> +	status = SHUTTING_DOWN; /* BUGGY!!! */\lnlbl[store:a]
> +	start_shutdown();
> +	while (!other_task_ready)\lnlbl[loop:b]
> +		continue;\lnlbl[loop:e]
> +	finish_shutdown();\lnlbl[finish]
> +	status = SHUT_DOWN;\lnlbl[store:b]
> +	do_something_else();
>  }
> -\centering
> -\theverbbox
> +
> +void work_until_shut_down(void)
> +{
> +	while (status != SHUTTING_DOWN)\lnlbl[until:loop:b]
> +		do_more_work();\lnlbl[until:loop:e]
> +	other_task_ready = 1; /* BUGGY!!! */\lnlbl[other:store]
> +}
> +\end{VerbatimL}
> +\end{linelabel}
>  \caption{C Compilers Can Fuse Stores}
>  \label{lst:toolsoftrade:C Compilers Can Fuse Stores}
>  \end{listing}
>  
>  However, there are exceptions, for example as shown in
>  Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Stores}.
> +\begin{lineref}[ln:toolsoftrade:C Compilers Can Fuse Stores]
>  The function \co{shut_it_down(void)()} stores to the shared
> -variable \co{status} on lines~3 and~8, and so assuming that neither
> +variable \co{status} on lines~\lnref{store:a} and~\lnref{store:b},
> +and so assuming that neither
>  \co{start_shutdown()} nor \co{finish_shutdown()} access \co{status},
>  the compiler could reasonably remove the store to \co{status} on
> -line~3.
> +line~\lnref{store:a}.
>  Unfortunately, this would mean that \co{work_until_shut_down()} would
> -never exit its loop spanning lines~14 and~15, and thus would never set
> +never exit its loop spanning
> +lines~\lnref{until:loop:b} and~\lnref{until:loop:e}, and thus would never set
>  \co{other_task_ready}, which would in turn mean that \co{shut_it_down()}
> -would never exit its loop spanning lines~5 and~6, even if
> +would never exit its loop spanning
> +lines~\lnref{loop:b} and~\lnref{loop:e}, even if
>  the compiler chooses not to fuse the successive loads from
> -\co{(!other_task_ready} on line~5.
> +\co{(!other_task_ready)} on line~\lnref{loop:b}.
>  
>  And there are more problems with the code in
>  Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Stores},
> @@ -1889,16 +1894,19 @@ modern superscalar microprocessors.
>  It is also another reason why the code in
>  Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Stores}
>  is buggy.
> -For example, suppose that the \co{do_more_work()} function on line~15
> +For example, suppose that the \co{do_more_work()} function on
> +line~\lnref{until:loop:e}
>  does not access \co{other_task_ready}.
>  Then the compiler would be within its rights to move the assignment
> -to \co{other_task_ready} on line~16 to precede line~14, which might
> +to \co{other_task_ready} on
> +line~\lnref{other:store} to precede line~\lnref{until:loop:b}, which might
>  be a great disappointment for anyone hoping that the last call to
> -\co{do_more_work()} on line~15 happens before the call to
> -\co{finish_shutdown()} on line~7.
> +\co{do_more_work()} on line~\lnref{until:loop:e} happens before the call to
> +\co{finish_shutdown()} on line~\lnref{finish}.
> +\end{lineref}
>  
>  {\bf Invented loads} were illustrated by the code in
> -Listings~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style})
> +Listings~\ref{lst:toolsoftrade:Living Dangerously Early 1990s Style}
>  and~\ref{lst:toolsoftrade:C Compilers Can Invent Loads},
>  in which the compiler optimized away a temporary variable,
>  thus loading from a shared variable more often than intended.
> @@ -1910,50 +1918,49 @@ These hoisting optimizations are not uncommon, and can cause significant
>  increases in cache misses, and thus significant degradation of
>  both performance and scalability.
>  
> +\begin{lineref}[ln:toolsoftrade:C Compilers Can Fuse Stores]
>  {\bf Invented stores} can occur in a number of situations.
>  For example, a compiler emitting code for \co{work_until_shut_down()} in
>  Listing~\ref{lst:toolsoftrade:C Compilers Can Fuse Stores}
>  might notice that \co{other_task_ready} is not accessed by
> -\co{do_more_work()}, and stored to on line~16.
> +\co{do_more_work()}, and stored to on line~\lnref{other:store}.
>  If \co{do_more_work()} was a complex inline function, it might be
>  necessary to do a register spill, in which case one attractive
>  place to use for temporary storage is \co{other_task_ready}.
>  After all, there are no accesses to it, so what is the harm?
>  
>  Of course, a non-zero store to this variable at just the wrong time
> -would result in the \co{while} loop on line~5 terminating
> +would result in the \co{while} loop on
> +line~\lnref{loop:b} terminating
>  prematurely, again allowing \co{finish_shutdown()} to run
>  concurrently with \co{do_more_work()}.
>  Given that the entire point of this \co{while} appears to be to
>  prevent such concurrency, this is not a good thing.
> +\end{lineref}
>  
>  \begin{listing}[tbp]
> -{ \scriptsize
> -\begin{verbbox}
> - 1 if (condition)
> - 2   a = 1;
> - 3 else
> - 4   do_a_bunch_of_stuff();
> -\end{verbbox}
> -}
> -\centering
> -\theverbbox
> +\begin{linelabel}[ln:toolsoftrade:Inviting an Invented Store]
> +\begin{VerbatimL}[commandchars=\\\{\}]
> +if (condition)
> +	a = 1;
> +else
> +	do_a_bunch_of_stuff();
> +\end{VerbatimL}
> +\end{linelabel}
>  \caption{Inviting an Invented Store}
>  \label{lst:toolsoftrade:Inviting an Invented Store}
>  \end{listing}
>  
>  \begin{listing}[tbp]
> -{ \scriptsize
> -\begin{verbbox}
> - 1 a = 1;
> - 2 if (!condition) {
> - 3   a = 0;
> - 4   do_a_bunch_of_stuff();
> - 5 }
> -\end{verbbox}
> +\begin{linelabel}[ln:toolsoftrade:Compiler Invents an Invited Store]
> +\begin{VerbatimL}[commandchars=\\\[\]]
> +a = 1;\lnlbl[store:uncond]
> +if (!condition) {
> +	a = 0;\lnlbl[store:cond]
> +	do_a_bunch_of_stuff();
>  }
> -\centering
> -\theverbbox
> +\end{VerbatimL}
> +\end{linelabel}
>  \caption{Compiler Invents an Invited Store}
>  \label{lst:toolsoftrade:Compiler Invents an Invited Store}
>  \end{listing}
> @@ -1971,9 +1978,12 @@ might know that the value of \co{a} is initially zero,
>  which might be a strong temptation to optimize away one branch
>  by transforming this code to that in
>  Listing~\ref{lst:toolsoftrade:Compiler Invents an Invited Store}.
> -Here, line~1 unconditionally stores \co{1} to \co{1}, then
> -resets the value back to zero on line~3 if \co{condition} was not set.
> +\begin{lineref}[ln:toolsoftrade:Compiler Invents an Invited Store]
> +Here, line~\lnref{store:uncond} unconditionally stores \co{1} to \co{a}, then
> +resets the value back to zero on
> +line~\lnref{store:cond} if \co{condition} was not set.
>  This transforms the if-then-else into an if-then, saving one branch.
> +\end{lineref}
>  
>  Finally, pre-C11 compilers could invent writes to unrelated
>  variables that happened to be adjacent to written-to
> -- 
> 2.7.4
> 


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-10-06  3:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-05 15:38 [PATCH] toolsoftrade: Employ new scheme for snippet in newly added sections Akira Yokosawa
2018-10-05 20:56 ` Paul E. McKenney

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.