Commit e1364050 authored by Hans Buchmann's avatar Hans Buchmann

Amdahls law Consumer-Producer

parent d3af8124
\begin{frame}{Amdahls Law}
\begin{itemize}
\item zeigt eine Grenze auf die nicht berschritten werden kann
\begin{itemize}
\item la Zweiter Haupsatz der Thermodynamik
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}{Gene Amdahl: 1922-}{Entdeckt 1967}
\begin{center}
\includegraphics[height=6cm]{Amdahl_march_13_2008.jpg}
\end{center}
{\tiny \copyright Pkivolowitz at en.wikipedia}
\end{frame}
\begin{frame}{Amdahls Law}{Die Vorbereitungen}
\begin{description}[Excecution Time]
\item[Program] das parallelisierbar ist
% \vspace{2mm}
% \remark{not a \poc}
\item[Excecution Time] fr das Programm mit einer CPU
\end{description}
\fig{fig/program-execution-time.pdf}{0.5}{0}
\end{frame}
\begin{frame}{Parallelisierung}
\fig{fig/program-execution-parallelizable.pdf}{0.5}{0}
\vspace{2mm}
\begin{remarks}
\item $t_p$ Zeit die parallelisiert werden knnte
\item Die Abbildung gilt fr eine CPU {\color{green} {\bf kann aber}}
\begin{itemize}
\item {\color{green}
parallelisiert werden}
\end{itemize}
\item Die Aufteilung
\begin{itemize}
\item {\em sequentiell} vs. {\em parallelisierbar}
\end{itemize}
nicht einfach
\end{remarks}
\end{frame}
\begin{frame}{Mit $n$ CPUs}
\fig{fig/program-execution-n-processors.pdf}{0.5}{0}
\begin{description}
\item[SpeedUp]
\[
s=\frac{ExecutionTime_{n=1}}{ExecutionTime_{n\ge 1}} \ge 1
\]
\end{description}
\end{frame}
\subsection{Die Formel}
\begin{frame}{Amdahls Law}{Die Formel}
\fig{fig/program-execution-n-processors.pdf}{0.375}{0}
\[
s=\frac{t_e}{(t_e-t_p)+\frac{t_p}{n}}
\]
with $P=\frac{t_p}{t_e}$ for the {\em Parallel Part}
\[
s=\frac{1}{(1-P)+\frac{P}{n}}
\]
\end{frame}
\begin{frame}{Ein paar Beispiele}
\fig{fig/amdahl.pdf}{0.5}{0}
\end{frame}
\begin{frame}{Obere Grenze}
\[
s=\frac{1}{(1-P)+\frac{P}{n}}
\]
\begin{description}
\item[Obere Grenze] $n=\infty$:
\begin{itemize}
\item Parallele Teil in sehr kurzer Zeit $0$
\end{itemize}
\[
s_{\infty}=\frac{1}{(1-P)}
\]
\end{description}
\end{frame}
%\subsection{An Example}
%\begin{frame}{An example}{Generating the frames of a movie}
% \begin{description}[For every frame]
% \item[The Unit] a pixel
% \item[For every frame]
% \begin{tabular}{r|c|l|l}
% &p & t& \\
% \hline
% \hline
% \cod{Load} &no & 0.1 & the scene \\
% \hline
% \cod{Render}&yes & 1 & the frame \\
% \hline
% \cod{Store} &no& 0.5 &on harddisk
% \end{tabular}
% \begin{description}
% \item[p] Parallelizable
% \item[t] Execution Time
% \end{description}
% \end{description}
% \begin{eqnarray*}
% P = \frac{1}{1.6} = \frac{5}{8}\\
% s_{\infty} = \frac{8}{3}
% \end{eqnarray*}
%\end{frame}
\section{Consumer Producer}
\begin{frame}{Wichtige Begriffe}
\begin{itemize}
\item volatile
\item synchronized
\item wait/notify
\end{itemize}
\end{frame}
\begin{codedemo}{Consumer Producer}
\fig{fig/consumer-producer.pdf}{0.625}{0}
\begin{block}{Regel}
Jedes produzierte Ding {\Huge $\bullet$} darf genau einmal konsumiert
werden\\
$\#produced=\#consumed$\footnote{\#: Anzahl}
\end{block}
\end{codedemo}
\begin{codedemo}{Die Klassen \rev{ConsumerProducer.java}{3833}}
\begin{description}[Consumer]
\item[Item] Das produzierte/konsumierte {\em Ding}
\item[Pool] Platz hchstens ein {\em Item}
\item[Agent] Abstrakte Oberklasse von \cod{Producer}, \cod{Consumer}\\
\cod{Runnable}, die Unterklassen implementieren \cod{run}
\item[Producer] Unterklasse von \cod{Agent}\\
produziert {\em Item}s
\item[Consumer] Unterklasse von \cod{Agent},\\
konsumiert {\em Item}s
\end{description}
\end{codedemo}
\begin{codedemo}{Erste Lsung}
\begin{itemize}
\item \cod{get}/\cod{put} Implementation
\item 1 Producer 1 Consumer
\item \cod{volatile}
\begin{itemize}
\item im \cod{Pool}: \cod{Item {\bf volatile} theItem;}
\end{itemize}
\item 1 Producer 2 Consumer
\item Zwei {\em Consumer}
\item das gleiche doppelt konsumiert
\end{itemize}
\end{codedemo}
\begin{codedemo}{Szenario: Zwei {\em Consumer}}
\begin{columns}
\begin{column}{4cm}
\listing{get.java}
\end{column}
\begin{column}{6cm}
\begin{tabular}{c||c|c||c|c}
theThing & $pc_{0}$ & $sth_{0}$ & $pc_{1}$ & $sth_{1}$\\
\hline
$p$ & $6$ & $p$ & &\\
& & & $6$ & $p$\\
\end{tabular}
\end{column}
\end{columns}
\begin{block}{Bilanz}
$theThing$ $p$ wird {\em zweimal} konsumiert
\end{block}
\end{codedemo}
%\begin{codedemo}{\rev{ConsumerProducer.java}{3850}}
% \begin{itemize}
% \item \cod{Agent.cnt}, lokal
% \item 2 {\em Consumer}
% \item Bilanz in in \cod{main}
% \item \cod{cnt} \cod{Pool.get}
% \end{itemize}
%\end{codedemo}
\begin{codedemo}{\rev{ConsumerProducer.java}{3851} synchronized}
\begin{columns}[t]
\begin{column}{6cm}
{\tt
\begin{tabbing}
synchronized\\Item get()\\
\{\\
\}
\end{tabbing}
}
\end{column}
\begin{column}{5cm}
{\tt
\begin{tabbing}
So\=mething get()\\
\{\\
\>synchronized(this)\\
\>\{\\
\>\}\\
\}
\end{tabbing}
}
\end{column}
\end{columns}
\end{codedemo}
\begin{codedemo}{Szenario: Deadlock}
\begin{columns}
\begin{column}{4.5cm}
\begin{description}
\item[c] ein \cod{Consumer}
\item[p] ein \cod{Producer}
\end{description}
\end{column}
\begin{column}{9cm}
\begin{itemize}
\item {\cod{\Huge p}} betritt zweimal hintereinander den \cod{pool}
\begin{itemize}
\item {\cod{\Huge c}} wartet
\item {\cod{\Huge p}} luft ($100\%$)
\end{itemize}
\end{itemize}
\end{column}
\end{columns}
\fig{fig/dead-lock.pdf}{0.75}{0}
\end{codedemo}
\begin{codedemo}{\cod{wait}/\cod{notify} \rev{ConsumerProducer.java}{3851}}
\begin{itemize}
\item Beschreibung
\begin{itemize}
\item \cod{Object.wait}
\item \cod{Object.notify}
\item \cod{Object.notifyAll}
\end{itemize}
\item \cod{Object.notify} vs. \cod{Object.notifyAll}
\end{itemize}
\end{codedemo}
......@@ -2,6 +2,7 @@
%threads
%(c) H.Buchmann FHNW 2010
%$Id$
%export TEXINPUTS=.:${HOME}/fhnw/edu/config//:${HOME}/fhnw/mse/slides/2-execution-environment//:
%------------------------
\documentclass{beamer}
\usepackage{latex/beamer}
......@@ -362,126 +363,9 @@ void doSomething();
\end{itemize}
\end{frame}
\section{Consumer Producer}
\begin{codedemo}{Consumer Producer}
\fig{fig/consumer-producer.pdf}{0.625}{0}
\begin{block}{Regel}
Jedes produzierte Ding {\Huge $\bullet$} darf genau einmal konsumiert
werden\\
$\#produced=\#consumed$\footnote{\#: Anzahl}
\end{block}
\end{codedemo}
\begin{codedemo}{Die Klassen \rev{ConsumerProducer.java}{3833}}
\begin{description}[Something]
\item[Something] Das produzierte/konsumierte {\em Ding}
\item[Pool] Platz hchstens ein {\em Something}
\item[Agent] Abstrakte Oberklasse von \cod{Producer}, \cod{Consumer}\\
\cod{Runnable}, die Unterklassen implementieren \cod{run}
\item[Producer] Unterklasse von \cod{Agent}\\
produziert {\em Something}s
\item[Consumer] Unterklasse von \cod{Agent},\\
konsumiert {\em Something}s
\end{description}
\end{codedemo}
\section{Amdahls Law}
\input{amdahl-law.tex}
\begin{codedemo}{Erste Lsung}
\begin{itemize}
\item \cod{get}/\cod{put} Implementation
\item 1 Producer 1 Consumer
\item steht still: warum ?
\item \cod{volatile}
\item Zwei {\em Consumer}
\item das gleiche doppelt konsumiert
\end{itemize}
\end{codedemo}
\begin{codedemo}{Szenario: Zwei {\em Consumer}}
\begin{columns}
\begin{column}{4cm}
\listing{get.java}
\end{column}
\begin{column}{6cm}
\begin{tabular}{c||c|c||c|c}
theThing & $pc_{0}$ & $sth_{0}$ & $pc_{1}$ & $sth_{1}$\\
\hline
$p$ & $6$ & $p$ & &\\
& & & $6$ & $p$\\
\end{tabular}
\end{column}
\end{columns}
\begin{block}{Bilanz}
$theThing$ $p$ wird {\em zweimal} konsumiert
\end{block}
\end{codedemo}
%\begin{codedemo}{\rev{ConsumerProducer.java}{3850}}
% \begin{itemize}
% \item \cod{Agent.cnt}, lokal
% \item 2 {\em Consumer}
% \item Bilanz in in \cod{main}
% \item \cod{cnt} \cod{Pool.get}
% \end{itemize}
%\end{codedemo}
\begin{codedemo}{\rev{ConsumerProducer.java}{3851} synchronized}
\begin{columns}[t]
\begin{column}{6cm}
{\tt
\begin{tabbing}
synchronized\\Something get()\\
\{\\
\}
\end{tabbing}
}
\end{column}
\begin{column}{5cm}
{\tt
\begin{tabbing}
So\=mething get()\\
\{\\
\>synchronized(this)\\
\>\{\\
\>\}\\
\}
\end{tabbing}
}
\end{column}
\end{columns}
\end{codedemo}
\begin{codedemo}{Szenario: Deadlock}
\begin{columns}
\begin{column}{4.5cm}
\begin{description}
\item[c] ein \cod{Consumer}
\item[p] ein \cod{Producer}
\end{description}
\end{column}
\begin{column}{9cm}
\begin{itemize}
\item {\cod{\Huge p}} betritt zweimal hintereinander den \cod{pool}
\begin{itemize}
\item {\cod{\Huge c}} wartet
\item {\cod{\Huge p}} luft ($100\%$)
\end{itemize}
\end{itemize}
\end{column}
\end{columns}
\fig{fig/dead-lock.pdf}{0.75}{0}
\end{codedemo}
\begin{codedemo}{\cod{wait}/\cod{notify} \rev{ConsumerProducer.java}{3851}}
\begin{itemize}
\item Beschreibung
\begin{itemize}
\item \cod{Object.wait}
\item \cod{Object.notify}
\item \cod{Object.notifyAll}
\end{itemize}
\item \cod{Object.notify} vs. \cod{Object.notifyAll}
\end{itemize}
\end{codedemo}
\input{consumer-producer.tex}
\end{document}
......@@ -4,68 +4,50 @@
//$Id$
//------------------
class Something //the thing to be produced/consumed
class Item //the thing to be produced/consumed
{
private String val;
Something(String val)
final Producer prod;
final long val;
Item(Producer prod,
long val)
{
this.prod=prod;
this.val=val;
}
public String toString()
{
return val;
return ""+val;
}
}
class Pool //for the somethings
{
private volatile Something theThing; //empty or full
private volatile long cnt;
private Item volatile theItem; //empty or full
Pool()
{
theThing=null;
theItem=null;
}
synchronized void put(Something sth)
{
try
{
while(theThing!=null) //wait until empty
{
wait();
}
theThing=sth;
notifyAll();
}
catch(Exception ex)
void put(Item it)
{
while(theItem!=null)
{
ex.printStackTrace();
System.exit(0);
}
//now empty
theItem=it;
}
synchronized Something get()
Item get()
{
try
while(theItem==null)
{
while(theThing==null) //wait until not empty
{
wait();
}
Something sth=theThing;
cnt=1l<<20;
while(cnt>0){--cnt;}
theThing=null; //now empty
notifyAll();
return sth;
}
catch(Exception ex)
{
ex.printStackTrace();
System.exit(0);
return null;
}
//now full
Item it=theItem;
theItem=null; //consumed
return it;
}
}
......@@ -75,66 +57,89 @@ abstract class Agent implements Runnable
protected String id;
protected Pool pool; //reference
private Thread th=new Thread(this);
private static final long CNT=(1<<20);
protected Agent(String id,Pool pool)
{
this.id=id;
this.pool=pool;
th.start();
}
protected void start()
abstract void doIt();
abstract void balance();
public void run()
{
long cnt=CNT;
while(cnt>0)
{
--cnt;
doIt();
}
}
void join() throws Exception //called in main thread
{
th.start();
}
th.join();
}
}
class Producer extends Agent
{
private int id=0;
private long val=0;
Producer(String id,Pool pool)
{
super(id,pool); //initialize superclass
start();
}
void doIt()
{
Item it=new Item(this,val);
pool.put(it);
++val;
}
//implementation Runnable
public void run()
{
while(true)
{
Something sth=new Something(super.id+":"+id);
pool.put(sth);
++id;
}
void balance()
{
System.out.println("Producer "+id+": "+val+" items");
}
}
class Consumer extends Agent
{
private long consumed=0;
Consumer(String id,Pool pool)
{
super(id,pool); //initialize superclass
start();
}
public void run()
void doIt()
{
while(true)
{
Something sth=pool.get();
System.err.println(sth);
}
Item it=pool.get();
++consumed;
}
void balance()
{
System.out.println("Consumer "+id+": items "+consumed);
}
}
//the main class
class ConsumerProducer
{
public static void main(String args[])
public static void main(String args[]) throws Exception
{
Pool pool=new Pool(); //one instance
new Consumer("c0",pool);
new Producer("p0",pool);
new Consumer("c1",pool);
Agent a0=new Consumer("c0",pool);
Agent a1=new Producer("p0",pool);
// Agent a2=new Consumer("c1",pool);
a0.join();
a1.join();
// a2.join();
a0.balance();
a1.balance();
// a2.balance();
}
}
//------------------
//ConsumerProducer
//(c) H.Buchmann FHNW 2007
//$Id$
//------------------
class Something //the thing to be produced/consumed
{
private String val;
Something(String val)
{
this.val=val;
}
public String toString()
{
return val;
}
}
class Pool //for the somethings
{
private volatile Something theThing; //empty or full
private volatile long cnt;
Pool()
{
theThing=null;
}
synchronized void put(Something sth)
{
try
{
while(theThing!=null) //wait until empty
{
wait();
}
theThing=sth;
notifyAll();
}
catch(Exception ex)
{
ex.printStackTrace();
System.exit(0);
}
}
synchronized Something get()
{
try
{
while(theThing==null) //wait until not empty
{
wait();
}
Something sth=theThing;
cnt=1l<<20;
while(cnt>0){--cnt;}
theThing=null; //now empty
notifyAll();
return sth;
}
catch(Exception ex)
{
ex.printStackTrace();
System.exit(0);
return null;
}
}
}
abstract class Agent implements Runnable
{
protected String id;
protected Pool pool; //reference
private Thread th=new Thread(this);
protected Agent(String id,Pool pool)
{
this.id=id;
this.pool=pool;
}
protected void start()
{
th.start();
}
}
class Producer extends Agent
{
private int id=0;
Producer(String id,Pool pool)
{
super(id,pool); //initialize superclass
start();
}
//implementation Runnable
public void run()