Synchronized local and server repository.

parent 37ae6683
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{enumerate}
\usepackage{color}
% dot graphs
\usepackage{dot2texi}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows}
% predefined styles
\newcommand{\wrong}[1]{{\color{red}\underline{\textbf{{#1}}}}}
\author{Sander van Veen (UvA ID: 6167969) \\ University of Amsterdam}
\title{Automata answers}
\begin{document}
\maketitle
\tableofcontents
\pagebreak
\section{Assignments part I}
\subsection*{Assignment 1}
\begin{enumerate}[(a)]
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR;
node [shape="none"]; start ;
node [shape="box",color="blue"]; q_0;
node [shape="circle",color="black"]; q_1 q_2 q_3;
start -> q_0;
q_0 -> q_1 [label="1"];
q_1 -> q_0 [label="1"];
q_1 -> q_2 [label="0"];
q_2 -> q_1 [label="0"];
q_2 -> q_3 [label="1"];
q_3 -> q_2 [label="1"];
q_3 -> q_0 [label="0"];
q_0 -> q_3 [label="0"];
}
\end{dot2tex}
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR;
node [shape="circle",color="black"]; q_0;
node [shape="none"]; start ;
start -> q_0;
q_0 -> q_0 [label="1"];
node [shape="box",color="blue"]; q_1;
q_0 -> q_1 [label="0"];
q_1 -> q_0 [label="0, 1"];
}
\end{dot2tex}
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR;
node [shape="circle",color="black"]; q_0 q_1;
node [shape="none"]; start ;
start -> q_0;
q_0 -> q_0 [label="1"];
q_0 -> q_1 [label="0"];
q_1 -> q_0 [label="1"];
node [shape="box",color="blue"]; q_2;
q_1 -> q_2 [label="0"];
q_2 -> q_0 [label="1"];
q_2 -> q_2 [label="0"];
}
\end{dot2tex}
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR;
node [shape="box",color="blue"]; q_0 q_1 q_2 q_3 q_4 q_6 q_7 q_8 q_9 q_10;
node [shape="circle",color="black"]; q_5;
q_0 -> q_1 [label="1"];
q_1 -> q_2 [label="1"];
q_2 -> q_3 [label="1"];
q_3 -> q_4 [label="1"];
q_4 -> q_5 [label="1"];
q_5 -> q_5 [label="0, 1"];
q_0 -> q_6 [label="0"];
q_1 -> q_7 [label="0"];
q_2 -> q_8 [label="0"];
q_3 -> q_9 [label="0"];
q_4 -> q_10 [label="0"];
q_6 -> q_7 [label="0, 1"];
q_7 -> q_8 [label="0, 1"];
q_8 -> q_9 [label="0, 1"];
q_9 -> q_10 [label="0, 1"];
q_10 -> q_0 [label="0, 1"];
}
\end{dot2tex}
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR
node [shape="none"]; start ;
node [shape="box",color="blue"]; q_0 q_1 q_2 q_3 q_4 q_5;
node [shape="circle",color="black"]; q_6 q_7;
start -> q_0;
q_0 -> q_1 [label="0"];
q_0 -> q_2 [label="1"];
q_1 -> q_3 [label="0"];
q_1 -> q_5 [label="1"];
q_5 -> q_7 [label="0"];
q_5 -> q_3 [label="1"];
q_7 -> q_3 [label="0, 1"];
q_2 -> q_4 [label="0"];
q_2 -> q_3 [label="1"];
q_4 -> q_3 [label="0"];
q_4 -> q_6 [label="1"];
q_6 -> q_3 [label="0, 1"];
q_3 -> q_3 [label="0, 1"];
}
\end{dot2tex}
\end{enumerate}
\subsection*{Assignment 2}
Given $ A = ( Q, \Sigma, \delta, q_0, F ) $. \\
Then $ B = ( Q, \Sigma, \delta, q_0, Q \setminus F ) $. L(B) is the complement of L(A).
\subsection*{Assignment 3}
\begin{enumerate}[(a)]
\item $ \{w \in \{a,b\}* | \, w $ ends with one $a$, followed by zero or more $b$'s$\} $
\item $ \{w \in \{a,b\}* | \, w $ contains substring of two $a$'s, followed by one $b\} $
\item $ \{w \in \{a,b\}* | \, w $ starts with one $a$, followed by one $b\} $
\end{enumerate}
\subsection*{Assignment 4}
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR
node [shape="none"]; start ;
node [shape="box",color="blue"]; q_1 q_5;
node [shape="circle",color="black"]; q_0 q_2 q_3 q_4;
start -> q_0;
q_0 -> q_1 [label="[0,9]"];
q_1 -> q_1 [label="[0,9]"];
q_1 -> q_2 [label="."];
q_2 -> q_1 [label="[0,9]"];
q_1 -> q_3 [label="E"];
q_3 -> q_4 [label="-"];
q_4 -> q_5 [label="[0,9]"];
q_3 -> q_5 [label="[0,9]"];
q_5 -> q_5 [label="[0,9]"];
}
\end{dot2tex}
\pagebreak
\subsection*{Assignment 5}
In order to draw a reasonable graph, the alphabet is limited to \{0,1,2\}.
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR
node [shape="none"]; start;
node [shape="box",color="blue"]; q_1 q_2 q_4;
node [shape="circle",color="black"]; q_0 q_3 q_6;
node [shape="box",color="blue"]; q_5 q_7;
node [shape="none",label="..."]; q_8 q_9;
start -> q_0;
q_0 -> q_1 [label="0"];
q_0 -> q_8 [label="1"];
q_0 -> q_9 [label="2"];
q_1 -> q_2 [label="1"];
q_2 -> q_3 [label="\{0,1\}"];
q_2 -> q_4 [label="2"];
q_3 -> q_4 [label="2"];
q_3 -> q_3 [label="\{0,1\}"];
q_1 -> q_5 [label="2"];
q_5 -> q_6 [label="\{0,2\}"];
q_5 -> q_7 [label="1"];
q_6 -> q_7 [label="1"];
q_6 -> q_6 [label="\{0,2\}"];
}
\end{dot2tex}
\section{Assignments part II}
\subsection*{Assignment 6}
\begin{enumerate}[(a)]
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR
node [shape="none"]; start ;
node [shape="box",color="blue"]; q_1 q_2;
node [shape="circle",color="black"]; q_0 q_3;
start -> q_0;
q_0 -> q_1 [label="a"];
q_0 -> q_2 [label="b"];
q_1 -> q_1 [label="a"];
q_1 -> q_2 [label="b"];
q_2 -> q_3 [label="\{a,b\}"];
q_3 -> q_3 [label="\{a,b\}"];
}
\end{dot2tex}
\item[(d)]
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR
node [shape="none"]; start ;
node [shape="box",color="blue"]; q_0 q_1 q_2 q_3;
node [shape="circle",color="black"]; q_4;
start -> q_0;
q_0 -> q_0 [label="b"];
q_0 -> q_1 [label="a"];
q_1 -> q_2 [label="a"];
q_1 -> q_4 [label="b"];
q_2 -> q_3 [label="b"];
q_2 -> q_4 [label="a"];
q_3 -> q_3 [label="\{a,b\}"];
q_4 -> q_4 [label="a"];
q_4 -> q_3 [label="b"];
}
\end{dot2tex}
\end{enumerate}
\subsection*{Assignment 7}
$ r = (ab + aa + baa)* $
\begin{center}
\begin{tabular}{|l|l|l|l|l|l|}
\hline
$w$ & bbaaba & abaabaaabaa & aaaabaaaa & baaaaabaa & baaaaabaaaab \\
\hline
$w \in L(r)$ & no: \wrong{b}baaba & yes & yes & yes & no: baaaaabaaaa\wrong{b} \\
\hline
\end{tabular}
\end{center}
\subsection*{Assignment 9}
\begin{enumerate}[(a)]
\item $(a+b)(a+b)$
\item $(a+b)(a+b)(a+b)(a+b)*$
\item $a(a+b)*a$
\item $(a+b)*(a(bb+\epsilon)+b(aa+\epsilon)+(a+b)(a+b+aa+bb))*(a+b)*$
\item $( \, (b+\epsilon) \, a \, (b+\epsilon) \, a \, (b+\epsilon) \, a \, (b+\epsilon) \, )*$
\item ?
\item $((a+b)*(a+b+ba))+\epsilon$
\item $b*(a+bb)*b*$
\end{enumerate}
\subsection*{Assignment 14}
\begin{enumerate}[(a)]
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR;
node [shape="none"]; start ;
node [shape="box",color="blue"]; q_2;
node [shape="circle",color="black"]; q_0 q_1;
start -> q_0;
q_0 -> q_0 [label="a"];
q_0 -> q_1 [label="b"];
q_0 -> q_2 [label="c"];
q_1 -> q_1 [label="a"];
q_1 -> q_2 [label="\{b,c\}"];
q_2 -> q_0 [label="c"];
q_2 -> q_2 [label="\{a,b\}"];
}
\end{dot2tex}
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR;
node [shape="none"]; start ;
node [shape="box",color="blue"]; q_0 q_1 q_2 q_3 q_4;
node [shape="circle",color="black"]; q_5;
start -> q_0;
q_0 -> q_5 [label="a"];
q_0 -> q_1 [label="c"];
q_0 -> q_2 [label="b"];
q_1 -> q_5 [label="\{a,b,c\}"];
q_2 -> q_0 [label="a"];
q_2 -> q_3 [label="b"];
q_2 -> q_4 [label="c"];
q_3 -> q_5 [label="\{a,b,c\}"];
q_4 -> q_4 [label="c"];
q_4 -> q_0 [label="a"];
q_4 -> q_3 [label="b"];
q_5 -> q_5 [label="\{a,b,c\}"];
}
\end{dot2tex}
\end{enumerate}
\section{Assignments part III}
\subsection*{Assignment 16}
\begin{enumerate}[(a)]
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR;
node [shape="none"]; start ;
node [shape="box",color="blue"]; q_1 q_2 q_3;
node [shape="circle",color="black"]; q_0;
start -> q_0;
q_0 -> q_1 [label="a"];
q_1 -> q_1 [label="a"];
q_1 -> q_2 [label="b"];
q_2 -> q_2 [label="a"];
q_2 -> q_3 [label="b"];
q_3 -> q_3 [label="b"];
}
\end{dot2tex}
\item
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR;
node [shape="none"]; start ;
node [shape="box",color="blue"]; q_3 q_4;
node [shape="circle",color="black"]; q_0 q_1 q_2;
start -> q_0;
q_0 -> q_1 [label="a"];
q_1 -> q_2 [label="b"];
q_2 -> q_3 [label="a"];
q_3 -> q_4 [label="a"];
q_3 -> q_2 [label="b"];
q_4 -> q_2 [label="\{a,b\}"];
}
\end{dot2tex}
\end{enumerate}
\subsection*{Assignment 19}
\textbf{Pumping lemma} If a language $L$ is regular, then there exists a number
$p \geq 1$ (the pumping length) such that every string $uwv$ in $L$ with
$|w| \geq p$ can be written in the form $uwv = uxyzv$ with strings $x$, $y$ and
$z$ such that $|xy| \leq p, \; |y| \geq 1$ and $uxy^izv$ is in $L$ for every
integer $i \geq 0$.
\begin{enumerate}[(a)]
\item
\item
\item For example, use $w = a^n b^n, \; xy = a^n, \; z = b^n, \;
|y| >= 1$. \\
Pump $y$, so that $|xy| > |z|$. This will result in
$\#_a(w) \neq \#_b(w)$.
\item
\end{enumerate}
%\subsection*{Assignment 20}
%\begin{enumerate}[(a)]
% \item Regular, because $|v| = 2$ solves the ``counting problem'' for $v$.
% \item Regular, because the language is equivalent to
% $\{g \; | \; g \in \{a,b\}^*\}$.
%\end{enumerate}
% 16, 19abc, 20, 24ab, 26
\subsection*{Assignment 20}
If a regular expression $R$ has no occurrences of the empty language
$\varnothing$, then it is not empty. If the regular expression $R$ contains an
occurrence of the empty language, it may or may not be empty. \\
\\
\textbf{Basis:} \{\} denotes the empty language ($\epsilon$ does not). \\
\\
\textbf{Induction:}
\begin{enumerate}
\item $R = R_1 + R_2$ \\
$L(R)$ is empty iff $R_1$ and $R_2$ is empty.
\item $R = R_1 R_2$ \\
$L(R)$ is empty iff $R_1$ or $R_2$ is empty.
\item $R = R_1*$ \\
$L(R)$ not empty, since it always includes $\epsilon$.
\item $R = (R_1)$ \\
$R$ empty iff $R_1$ is empty.
\end{enumerate}
\section{Assignments part IV}
\subsection*{Assignment 35}
\begin{table}[h]
\begin{tabular}{ll}
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
graph G {
node [shape="none"]; S0 [label="S"] a0 [label="a"] ;
S1 [label="S"] a1 [label="a"] S2 [label="S"] b;
S3 [label="S"] e0 [label="\epsilon"] e1 [label="\epsilon"];
S0 -> a0;
S0 -> S1;
S1 -> a1;
S1 -> S2;
S1 -> b;
S1 -> S3;
S2 -> e0;
S3 -> e1;
}
\end{dot2tex}
&
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
graph G {
node [shape="none"]; S0 [label="S"] a0 [label="a"];
S1 [label="S"] b S2 [label="S"] a1 [label="a"];
S3 [label="S"] e0 [label="\epsilon"] e1 [label="\epsilon"];
S0 -> a0;
S0 -> S1;
S0 -> b;
S0 -> S2;
S1 -> a1;
S1 -> S3;
S2 -> e0;
S3 -> e1;
}
\end{dot2tex}
\end{tabular}
\caption{Two parse trees for $w = aab$}
\end{table}
Two leftmost derivations: \\
\\
$S \longrightarrow _{lm} aS \longrightarrow _{lm} aaSbS \longrightarrow _{lm}
aa \epsilon bS \longrightarrow _{lm} aa \epsilon b\epsilon \longrightarrow
aab $ \\
$S \longrightarrow _{lm} aSbS \longrightarrow _{lm} aaSbS \longrightarrow _{lm}
aa \epsilon bS \longrightarrow _{lm} aa \epsilon b\epsilon \longrightarrow
aab $ \\
\\
Two rightmost derivations: \\
\\
$S \longrightarrow _{rm} aS \longrightarrow _{rm} aaSbS \longrightarrow _{rm}
aaSb \epsilon \longrightarrow _{rm} aa \epsilon b \epsilon \longrightarrow
aab $ \\
$S \longrightarrow _{rm} aSbS \longrightarrow _{rm} aSb \epsilon
\longrightarrow _{rm} aaSb \epsilon \longrightarrow _{rm} aa \epsilon b\epsilon
\longrightarrow aab $
\subsection*{Assignment 36}
Unambiguous grammar of `` $ S \longrightarrow aS \; | \; aSbS \; |
\; \epsilon $ '': \\
\\
$ S \longrightarrow aST \; | \; \epsilon $ \\
$ T \longrightarrow bS \; | \; \epsilon $
\section*{Assignment 42}
\begin{enumerate}[1.]
\item
\item $P(G) = (\{q_0\}, \{a,b,s\}, \{a,b,s,A,S\}, \delta, q_0, S)$
\end{enumerate}
\end{document}
graph ER {
node [shape=box]; // entities
department;
manager;
location;
project;
employee;
family;
node [shape=ellipse]; // attributes
// department
{node [label="name"] name0;}
// manager
start;
// location
{node [label="name"] name1;}
{node [label="address"] address0;}
// project
{node [label="name"] name2;}
number;
// employee
{node [label="name"] name3;}
ssno;
{node [label="address"] address1;}
salary;
{node [label="born"] born0;}
// family
{node [label="name"] name4;}
{node [label="born"] born1;}
relationship
node [shape=diamond,style=filled,color=lightgrey]; // relations
"d-m";
"d-l";
"d-p";
"p-l";
"d-e";
"e-f";
"m-e";
//"C-I"; "S-C"; "S-I";
department -- name0;
department -- "d-m" [label="1"];
department -- "d-l" [label="*"];
department -- "d-p" [label="*"];
department -- "d-e" [label="*"];
"d-m" -- manager [label="*"];
manager -- start;
manager -- "m-e" [label="*"];
"p-l" -- location [label="*"];
"d-l" -- location [label="1"];
location -- name1;
location -- address0;
"d-p" -- project [label="1"];
project -- name2;
project -- number;
project -- "p-l" [label="1"];
"d-e" -- employee[label="1"];
"m-e" -- employee[label="1"];
employee -- name3;
employee -- ssno;
employee -- address1;
employee -- salary;
employee -- born0;
employee -- "e-f"[label="*"]
"e-f" -- family[label="*"];
family -- name4;
family -- born1;
family -- relationship;
//name0 -- course;
//code -- course;
//course -- "C-I" [label="n",len=1.00];
//"C-I" -- institute [label="1",len=1.00];
//institute -- name1;
//institute -- "S-I" [label="1",len=1.00];
//"S-I" -- student [label="n",len=1.00];
//student -- grade;
//student -- name2;
//student -- number;
//student -- "S-C" [label="m",len=1.00];
//"S-C" -- course [label="n",len=1.00];
//label = "\n\nEntity Relation Diagram\ndrawn by NEATO";
//fontsize=20;
}
Databases and ER-diagrams
Sander van Veen (6167969)
___________ Question 1: ________________
+----------------+
| Physical layer | Describes how a record is stored.
+----------------+
|
+---------------+
| Logical Layer | Describes data in database and
+---------------+ their relationships.
|
+------------+
| View layer | Application program which hide data types
+------------+ and optionally particular information.
___________ Question 2: ________________
DBMS
DBMS is short for database management system and is the general
term for a system used to manipulate a database.
DBA
DBA is an abbreviation for Database administrator, also known as a
supervisor. His job is to create, manage and tweak the database
design and some of its implementation (for example, the way the
data is stored).
DML
Data Manipulation Languages are used to manipulate a database.
SQL (structured query language) is most widely used. There are
two classes of DML's:
- Procedural, where a user specifies what data is required, and
how it should be found.
- Declarative, where a user specifies what data is required, but
does not specify how to find the data.
DDL
A Data Definition Language can describe how the data will be
stored. It uses metadata (in a schema) to separate the records.
Data model
Collection of tool describing data, relationships, semantics
and constrains (rules used to ensure data integrity).
Normalization
Separating repeated data into different tables, to prevent
redundancy and bad database design.
Query processing
User specifies a Query, which will start the following sequence:
=> Parser / Translator (convert SQL to algebra)
=> Relational algebra expression
=> Optimizer (with statistics about data)
=> Execution plan (how to find the data)
=> Evaluation engine (seeks through data)
=> Query output (returns the results)
Query optimization
Convert queries to better ones, to improve performance. For
example, only select records from tables which do matter,
before performing a Join-operation, instead of using all records.
___________ Question 3: ________________
The design process consists of the following phases:
o The initial phase gives a designer a better feeling about the data,
which will be used and is called "Specification of user requirements".
For example, this is the moment where you ask the manager of a supermarket
about what data is used and what the database should be able to do.
o The second phase is "conceptual-design", where the user requirements will
be translated to a conceptual database schema. This schema is a detailed
overview of the enterprise and used to confirm that all user requirements
are met. The relationships between the data is also described in this phase.
There are two ways to visualize the grouping of the various attributes,
used in the database schema:
- An entity relationship diagram, where an entity is an object (rectangle)
and various shapes (diamond, ellipse, or double bordered) and
(un)directional lines represent the relationships between the entities.
- Normalization, which is a set of algorithms used to generate tables.
o When the conceptual schema is designed, you can define a "specification of
functional requirements". This specification describes what kind of operations
the users can and cannot perform. For example, an employee of a supermarket
can (in most cases) not view the salary of the other employees. But a manager
has (in some cases) the authority to manipulate the salary of other employees.
o Once you have setup the functional requirements, you can start implementing
the design of the database. This phase is called "Logical design phase" and
differs from the "Conceptual design", because in this phase you can, for example,
specify the data types used for storing the data.
o The last phase is the "Physical design", where the features of the database are
specified. This phase also specifies the database engine (e.g. InnoDB, MyISAM)
to use and the internal storage structures (for example, file organisation).
___________ Question 4: ________________
4.1. Entity sets
The six rectangles (department, project, location, employee, manager and family) are
entities. Entities can be thought of as nouns. Every entity (except for weak entities)
have a primary key, which can be used for identification. An entity set is a collection
of multiple instances of an entity.
4.3. Relationship sets
In order to say something about two entities, they need a relationship. A collection of
multiple relationships between the same entities is called a relationship set. In the
ER diagram, these relationship sets are shown as grey diamonds and they connect the
entities using two or more lines (depending on the relationship).
4.5. Attributes for entity sets
A simple attribute is one component that is atomic. For example, project-number is a
property of a Project. Attributes are shown as ellipses in a ER diagram.
4.6. Primary keys
A primary key used to identify a member of an entity set. In a ER diagram, an attribute
with an underlined name is (part of) a primary key.
4.7. Composite attributes
A composite attribute has multiple components, each of which is atomic or composite.
For example, an attribute "name" is a composition of first- , given- and family name.
Composite attributes are shown as attributes of attributes, thus two or more ellipses,
where each is connected using a line to a single ellipse.
There are no composite attributes visible in the ER diagram of this assignment, because
they would make the diagram more difficult to read and thus irrelevant. An other example
of a composite attribute is "address", which can be split into street, city and house number.
4.8. Multi-valued attributes
A multi-valued attribute has more than one value for a particular entity. There are no
multi-valued attributes specified in the assignment and therefore not visible in the ER
diagram. However, a multi-valued attribute is shown as a ellipse with two borders.
4.9. Derived attributes
A derived attribute can be obtained from other attributes or related entities. The most
common example is the age of a person. It would be ridiculous to update the database for
each user, when a user celebrates his birthday. The age of a person can be obtained from
the user's date of birth. A derived attribute is shown as a dotted ellipse and line.
4.13. Weak entity sets
A weak entity is an entity, which relays on another entity. It is weak, because it cannot
be an entity on its own. Therefore, entities which are on its own, are called strong.
Weak entities are shown as normal entities, but with a second border.
4.14. Weak relationship sets
Weak relationships are relationships, which connect at least one weak entity to one or more
entities. Just like weak entities, weak relationships are shown as a normal relationship,
but with a second border. Please note that a weak relationship connected to a strong entity,
has a normal line and a double line when connected to a weak entity. Thus, the type of line
(double line or single line) refers to the connected type of entity (weak or strong).
\documentclass[a4paper]{article}
\usepackage[english]{babel}
%\usepackage[dutch]{babel}
\usepackage{url}
%importeren
\usepackage{graphicx}
\title{Databases assignment 2: Relational Schemas and Relational Algebra Query Language }
\author{Sander van Veen \\ UvA ID: 6167969}
\begin{document}
\maketitle
%\bigskip
%\tableofcontents
%\pagebreak
\section{Question 5}
To answer this question, I assume that the casual SQL database table naming convention (plurar table names and underscores between two or more words) is required. But, in almost every programming-language naming convention, only classes start with an uppercase letter. Thus, I think the naming convention in the book is confusing, because of the uppercase letter for relation schemas. Therefore, I will use the ActiveRecord naming convention.
To prevent ambiquity, I will not use verbs as the name of a crosstable. For example, it is not clear if the table ``works'' deals with persons, who works for a company or companies, which works for other companies. This ambiquity can be prevented, if the table's name is "persons\_companies" or "companies\_companies", instead of just the name "works".
Below is the relational schema for the given online shop's ER diagram:
\\
\\
products( \underline{product\_name}, category, price )\\
software\_products( \underline{product\_name}, platform )\\
educational\_products( \underline{product\_name}, age\_group )\\
\\
companies( \underline{companies\_name}, stockprice )\\
companies\_persons( \underline{companies\_name}, \underline{ssn} )\footnote{Alternative table name: ``employs''} \\
companies\_products( \underline{companies\_name}, \underline{products\_name} )\footnote{Alternative table name: ``makes''}\\
\\
persons( \underline{ssn}, persons\_name, address )\\
persons\_products( \underline{ssn}, \underline{products\_name} )\footnote{Alternative table name: ``buys''}\\
\section{Question 6a}
\subsection{Find the driver-ids of all persons, whose names are ``Jack''.}
$\Pi_{driver\_id}( \sigma_{name} = ``Jack" (person) )$
\subsection{Find the names of all persons who have a ``Golf'' car.}
$\Pi_{name}( \sigma_{person.driver-id} = _{owns.driver-id} ( person \times ( \sigma_{car.license} = _{owns.license} ( owns \times ( \sigma_{name} = ``Golf" (car) ) ) ) ) )$
\subsection{Find the report numbers of those accidents that either happened in ``Amsterdam'' or for which their damage amount was more than 10,000 Euro.}
$\Pi_{participated.report-number}( \sigma_{participated.report-number} = _{accident.report-number} ( participated \times ( \sigma_{location} = ``Amsterdam'' (accident) ) ) \bigcup \sigma_{participated.damage-amount} > 10000 ( participated) )$
\subsection{Find the names of those drivers that had accidents in ``Amsterdam'' from 2008 to 2009, and for which their cars were ``Golf''.}
$\Pi_{name}( \sigma_{participated.report-number} = _{accident.report-number} ( participated \times ( \sigma_{location} = ``Amsterdam'' \bigwedge date >= 2008 \bigwedge date < 2009 (accident) ) ) ) \bigcap \Pi_{name}( \sigma_{person.driver-id} = _{owns.driver-id} ( person \times ( \sigma_{car.license} = _{owns.license} ( owns \times ( \sigma_{name} = ``Golf" (car) ) ) ) ) )$
\subsection{For each city find the total sum of damage amounts of the accidents in that city.}
$\Pi_{location, total\_damage}( location G_{sum(damage-amount)} as total\_damage(accident) )$
\pagebreak
\section{Question 6b}
\subsection{Find those employees who live in ``Amsterdam'' but work for companies located outside ``Amsterdam''.}
$ \sigma_{company.city} \neq ``Amsterdam'' \bigwedge \sigma_{company.company-name} = _{works.company-name} ( company \times ( \sigma_{employee.employee-id} = _{works.employee-id} ( works \times ( \sigma_{city} = ``Amsterdam'' (employee) ) ) ) ) $
\subsection{Find the employee-id values of those employees who earn more than every employee working for ``Philips''.}
$ \Pi_{employee-id}( \sigma_{salary} > _{max\_salary} ( works \times \Pi_{max\_salary}( _{max(salary)} as _{max\_salary}( \sigma_{company-name} = ``Philips'' (works) ) ) ) $
\subsection{Find the company that has the biggest number of employees.}
$ \sigma_{total\_employees} = _{max(total\_employees)}( company-nameGcount(employee-id) as total\_employees (works) ) $
\end{document}
\ No newline at end of file
\documentclass[a4paper, 11pt]{article}
\usepackage[english]{babel}
%\usepackage[dutch]{babel}
\usepackage{url}
%handy commands
\newcommand{\tab}{\hspace*{2em}}
\newcommand{\tc} [1] {\textsc{#1}}
\title{Assignment 3 - SQL and QBE \\Databases for IN}
\author{Sander van Veen \\ 6167969 \\ \url{sandervv@gmail.com}}
\begin{document}
\maketitle
%table of contents is not really needed here
%\tableofcontents
\setcounter{section}{6}
\section{SQL}
\begin{enumerate}
%7.1
\item{Write a statement for creating the "City" table}
\tc{CREATE TABLE} `City` ( \\
\tab `Name` varchar(35) NOT NULL default '', \\
\tab `Country` varchar(4) NOT NULL default '', \\
\tab `Province` varchar(35) NOT NULL default '', \\
\tab `Population` int(11) default NULL, \\
\tab `Longitude` float default NULL, \\
\tab `Latitude` float default NULL, \\
\tab PRIMARY KEY (`Name`,`Country`,`Province`) \\
) \tc{ENGINE=MyISAM DEFAULT CHARSET=latin1};
%7.2
\item{Write a statement for deleting the "City" table}
\tc{DROP TABLE }`City` ;
%7.3
\item{Write a statement for deleting the column "Population" from the "City" table}
\tc{ALTER TABLE} `City` \tc{DROP COLUMN} `Population` ;
%7.4
\item{Select all languages spoken in the country "Belgium" and sort them alphabetically (Hint: Use the full
name "Belgium" as the part of your answer)}
\tc{SELECT} `Name` \\
\tc{FROM} `Language` \\
\tc{WHERE} `Country` = "B" \\
\tc{ORDER BY} `Name` ASC ;
%7.5
\item{Select the name of all of the mountains of the country "USA" (the country code of United States of
America) which are more than 2000 meters high}
\tc{SELECT} `Name` \\
\tc{FROM} `Mountain` \\
\tc{WHERE} `Name` \tc{IN} ( \\
\tab \tc{SELECT} `Mountain` \\
\tab \tc{FROM} `geo\_Mountain` \\
\tab \tc{WHERE} `Country` = "USA" \\
) \tc{AND} `Height` $>$ 2000 ;
%7.6
\item{Display the name and the height of all mountains that are located on islands}
SELECT I.Mountain, M.Height \\
FROM `MountainOnIsland` as I \\
LEFT JOIN Mountain as M ON I.Mountain = M.Name ;
%7.7
\item{Display the names of all cities in the country "USA" (the country code of United States of America) and remove possible duplicates}
SELECT DISTINCT Name \\
FROM `City` \\
WHERE Country = ``USA'' ;
%7.8
\item{Display the names of those countries that have deserts or mountains or both of them}
SELECT `Name` \\
FROM `Country` \\
WHERE Code IN ( \\
\tab SELECT DISTINCT `Country` \\
\tab FROM `geo\_Desert` \\
\tab UNION \\
\tab SELECT DISTINCT `Country` \\
\tab FROM `geo\_Mountain` \\
) ;
%7.9
\item{Calculate the total population of the world}
SELECT sum( `Population` ) as `world\_population` \\
FROM `Country` ;
%7.10
\item{Find the number of mountains per each country (by country code)}
SELECT `Country`, count(`Mountain`) as `total\_mountains` \\
FROM `geo\_Mountain` \\
GROUP BY `Country` ;
\setcounter{enumi}{11}
%7.12
\item{Find the rivers that pass through more than three provinces}
SELECT `River`, count(`Province`) as `through\_provinces` \\
FROM `geo\_River` \\
GROUP BY `River` \\
HAVING `through\_provinces` $>$ 3 ;
%7.13
\item{Display the names of the two countries that have the longest border}
SELECT `Name` \\
FROM `Country` \\
WHERE `Code` = ( \\
\tab SELECT `Country1` \\
\tab FROM `borders` \\
\tab ORDER BY `Length` DESC \\
\tab LIMIT 1 \\
) \\
OR `Code` = ( \\
\tab SELECT `Country2` \\
\tab FROM `borders` \\
\tab ORDER BY `Length` DESC \\
\tab LIMIT 1 \\
) \\
LIMIT 2;
%7.14
\item{Display the name of the country that has the maximum GDP}
SELECT `C`.`Name` \\
FROM `Economy` as `E` \\
LEFT JOIN `Country` as `C` ON `C`.`Code` = `E`.Country \\
ORDER BY `E`.`GDP` DESC \\
LIMIT 1;
%7.15
\item{Display the name of countries whose people do not speak English}
SELECT `Name` \\
FROM `Country` \\
WHERE `Code` NOT IN ( \\
\tab SELECT `Country` \\
\tab FROM `Language` \\
\tab WHERE `Name` = "English" \\
);
\pagebreak
\setcounter{enumi}{16}
%7.17
\item{Write a statement for inserting a record about a new organization in "Amsterdam"}
%AfDB African Development Bank Abidjan CI Cote dIvoire 1963-08-04
INSERT INTO `Organizations` ( `Abbreviation`, `Name`, `City`, `Country`, `Province`, `Established` ) \\
VALUES ( "adad", "Adad Ltd", "Amsterdam", "NL", "Noord-Holland", "2010-03-03" ) ;
%7.18
\item{Write a statement for updating the record that you created in question 7.17 by changing the establishment date of the organization}
UPDATE `Organizations` \\
SET `Established` = "2010-03-04" \\
WHERE `Abbreviation` = "adad" ;
%7.19
\item{Write a statement for deleting the record that you created in question 7.17}
DELETE FROM `Organizations` \\
WHERE `Abbreviation` = "adad" ;
\end{enumerate}
\section{QBE}
\begin{enumerate}
%8.1
\item{Select the names of all countries}
% l, c or r : justify left, center or right
% | vertical line
% || double vertical line
% & column separator
% \\ start new row
% \hline horizontal line
\begin{tabular}{|c|c|c|c|c|c|}
\hline
Name & Code & Capital & Province & Area & Population \\
\hline
P. & & & & & \\
\hline
\end{tabular}
%8.2
\item{Find the names of the languages that are spoken in the countries where the mountain called "Everest"
is located}
\begin{tabular}{|c|c|c|c|}
\hline
geo\_Mountain & Mountain & Country & Province \\
\hline
& Everest & \_x & \\
\hline
\end{tabular}
\begin{tabular}{|c|c|c|c|}
\hline
Languages & Country & Name & Percentage \\
\hline
& \_x & P.\_y & \\
\hline
\end{tabular}
\setcounter{enumi}{3}
%8.4
\item{Find all countries that have at least two spoken languages}
\begin{tabular}{|c|c|c|c|}
\hline
Languages & Country & Name & Percentage \\
\hline
& \_x & \_y & \\
& \_x & $\neg$\_y & \\
\hline
\end{tabular}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline
Country & Name & Code & Capital & Province & Area & Population \\
\hline
& P.\_z & \_x & & & & \\
\hline
\end{tabular}
%8.5
\item{Find the names of those languages that are spoken in at least two countries}
\begin{tabular}{|c|c|c|c|}
\hline
Languages & Country & Name & Percentage \\
\hline
& \_x & P.\_y & \\
& $\neg$\_x & \_y & \\
\hline
\end{tabular}
%8.6
\item{Find the total population of Asia}
\begin{tabular}{|c|c|c|}
\hline Continent & Name & Area \\
\hline & Asia & \_x \\
\hline \end{tabular}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline Country & Name & Code & Capital & Province & Area & Population \\
\hline & & & & & \_x & P.SUM.UNQ. \\
\hline
\end{tabular}
%8.7
\item{Find the total number of religions}
\begin{tabular}{|c|c|c|c|}
\hline Religion & Country & Name & Percentage \\
\hline & & P.UNQ.CNT. & \\
\hline
\end{tabular}
%8.8
\item{Find the names of the countries, as well as the types of government in those countries, that have the population growth higher than three percents}
\begin{tabular}{|c|c|c|c|}
\hline Population & Country & Population\_Growth & Infant\_Mortality \\
\hline & \_x & \_y & \\
\hline
\end{tabular}
\begin{tabular}{|c|}
\hline Conditions \\
\hline \_y $>$ 3 \\
\hline
\end{tabular}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline Country & Name & Code & Capital & Province & Area & Population \\
\hline & P.\_z & \_x & & & & \\
\hline
\end{tabular}
\begin{tabular}{|c|c|c|c|c|}
\hline Politics & Country & Indepencence & Dependent & Government \\
\hline & \_x & & & P.\_a \\
\hline
\end{tabular}
%8.9
\item{Find the name of neighboring countries for Switzerland}
\begin{tabular}{|c|c|c|c|}
\hline borders & Country1 & Country2 & Length \\
\hline & Switzerland & P.\_x & \\
\hline
\end{tabular}
\begin{tabular}{|c|c|c|c|}
\hline borders & Country1 & Country2 & Length \\
\hline & P.\_x & Switzerland & \\
\hline
\end{tabular}
%8.10
\item{Write a QBE query for changing the inflation in France to three percent}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline Economy & Country & GDP & Agriculture & Service & Industry & Inflation \\
\hline & F & & & & & U.3 \\
\hline
\end{tabular}
%8.11
\item{Write a QBE query for inserting a new organization into the organization table}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline Organization & Abbreviation & Name & City & Country & Province & Established \\
\hline I. & AbAb & Abla Abra & & & & \\
\hline
\end{tabular}
%8.12
\item{Write a QBE query for deleting the organization you inserted in the question 8.12}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline Organization & Abbreviation & Name & City & Country & Province & Established \\
\hline D. & AbAb & Abla Abra & & & & \\
\hline
\end{tabular}
\setcounter{enumi}{13}
%8.14
\item{Display the names of the countries that have no mountains passing through them}
\begin{tabular}{|c|c|c|c|}
\hline geo\_Mountain & Mountain & Country & Province \\
\hline & & \_x & \\
\hline
\end{tabular}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline Country & Name & Code & Capital & Province & Area & Population \\
\hline & P.\_y & $\neg$\_x & & & & \\
\hline
\end{tabular}
\end{enumerate}
\section*{Bonus question 2}
\textbf{Write the following queries in SQL:}
\begin{enumerate}
%bq-2.1
\item{Display the name of those countries which both have their GDP more than the one in "Poland" and do not have "English" as a spoken language. Sort the results alphabetically}
\texttt{SELECT Name \\
FROM Country \\
WHERE Code IN ( \\
\tab SELECT E.Country \\
\tab FROM `Economy` AS E \\
\tab INNER JOIN `Language` AS L \\
\tab ON `E`.`Country` = `L`.`Country` \\
\tab WHERE `E`.`GDP` > ( \\
\tab \tab \tab SELECT `GDP` FROM `Economy` WHERE `Country` = "PL" \\
\tab \tab ) AND `L`.Name != "English" \\
)\\
ORDER BY Name}
%bq-2.2
\item{Display the names of those countries that are neighbors of "France" but do not have "French" as a spoken language}
\texttt{SELECT Name \\
FROM Country \\
WHERE Code IN ( \\
\tab SELECT Country \\
\tab FROM borders \\
\tab INNER JOIN Language \\
\tab ON Country != "F" \\
\tab \tab AND ( Country1 = Country OR Country2 = Country ) \\
\tab WHERE ( Country1 = "F" OR Country2 = "F" ) \\
\tab \tab AND Country NOT IN ( \\
\tab \tab \tab SELECT Country FROM Language WHERE Name = "French" \\
\tab \tab ) \\
)}
\end{enumerate}
\textbf{Write the following query in QBE}:
\begin{enumerate}
\setcounter{enumi}{2}
%bq-2.3
\item{Display the names of all countries through which the longest river in the world passes}
First, I created this SQL query: \\
\texttt{SELECT Name \\
FROM Country \\
WHERE Code IN ( \\
\tab SELECT Country \\
\tab FROM geo\_River \\
\tab WHERE River = ( \\
\tab \tab SELECT Name \\
\tab \tab FROM River \\
\tab \tab WHERE Length = ( \\
\tab \tab \tab SELECT Max(Length) FROM River \\
\tab \tab ) \\
\tab ) \\
) }
Followed by the QBE-query:
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|}
\hline River & Name & River & Lake & Sea & Len & SLong & SLat & Mtns & SAlt & ELong & ELat \\
\hline & & & & & Max.\_l & & & & & & \\
\hline
\end{tabular}
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|}
\hline River & Name & River & Lake & Sea & Len & SLong & SLat & Mtns & SAlt & ELong & ELat \\
\hline & \_x & & & & \_y & & & & & & \\
\hline
\end{tabular}
\begin{tabular}{|c|}
\hline Conditions \\
\hline \_y = Max.\_l \\
\hline
\end{tabular}
\begin{tabular}{|c|c|c|c|}
\hline geo\_River & River & Country & Province \\
\hline & \_y & \_z & \\
\hline
\end{tabular}
\begin{tabular}{|c|c|c|c|c|c|c|}
\hline Country & Name & Code & Capital & Province & Area & Population \\
\hline & P.\_n & \_z & & & & \\
\hline
\end{tabular}
Note: Because the QBE-tables are too large to fit on a single page, I used abbreviations for the following names of the table columns: \\
``Len'' $\rightarrow$ ``Length'' \\
``SLong'' $\rightarrow$ ``SourceLongitude'' \\
``SLat'' $\rightarrow$ ``SourceLatitude'' \\
``Mnts'' $\rightarrow$ ``Mountains'' \\
``SAlt'' $\rightarrow$ ``SourceAltitude'' \\
``ELong'' $\rightarrow$ ``EstuaryLongitude''\\
``ELat'' $\rightarrow$ ``EstuaryLatitude''
\end{enumerate}
\end{document}
\documentclass[a4paper, 11pt]{article}
\usepackage[english]{babel}
\usepackage{url}
\title{Assignment 4 - Database Design and Functional Dependencies \\Databases for IN}
\author{Your Name \\ studentno \\ \url{yourmail@science.uva.nl}}
\begin{document}
\maketitle
%table of contents is not really needed here
%\tableofcontents
\section*{Question 9}
Consider the relation schema: $R = (A, B, C, D, E)$
with the following set F of functional dependencies
\[
\begin{array}{ccc}
A & \rightarrow & BC \\
CD & \rightarrow & E \\
B & \rightarrow & D \\
E & \rightarrow & A
\end{array}
\]
Find the candidate keys for R
\section*{Question 10}
Consider the relation schema: $R= (A, B, C, D, E, F)$
with the following set F of functional dependencies:
\[
\begin{array}{ccc}
A & \rightarrow & ABCDEF \\
B & \rightarrow & C \\
D & \rightarrow & E \\
\end{array}
\]
Decompose this schema into a set of schemas that are in 3NF. The decomposition should be lossless-join.
\end{document}
/* Computer Graphics, Assignment, Triangle Rasterization /*
* Computer Graphics, Assignment, Triangle Rasterization
* Filename ........ trirast.c * Filename ........ trirast.c
* Description ..... Implements triangle rasterization * Description ..... Implements triangle rasterization
* Date ............ 11.08.2008 * Date ............ 11.08.2008
* Created by ...... Paul Melis * Created by ...... Paul Melis
* *
* Student name .... Sander van Veen & Taddeus Kroes * Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com * Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 & 6054129 * Collegekaart .... 6167969 & 6054129
* Date ............ 09-09-2010 * Date ............ 09-09-2010
* Comments ........ * Comments ........
*/ */
...@@ -18,6 +19,8 @@ ...@@ -18,6 +19,8 @@
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#include <assert.h>
#include "types.h" #include "types.h"
#define MIN(x, y, z) fminf(fminf(x, y), z) #define MIN(x, y, z) fminf(fminf(x, y), z)
...@@ -28,6 +31,26 @@ ...@@ -28,6 +31,26 @@
#define X_DIFF(a, b) (y##a-y##b) #define X_DIFF(a, b) (y##a-y##b)
#define Y_DIFF(a, b) (x##b-x##a - (x-x_min)*(y##a-y##b)) #define Y_DIFF(a, b) (x##b-x##a - (x-x_min)*(y##a-y##b))
#define INIT_DELTA_RAST(a, b, c) {\
x_start = x##c; \
y_middle = y##b; \
\
dab = (x##b-x##a) / (y##b-y##a); \
dac = (x##c-x##a) / (y##c-y##a); \
dbc = (x##c-x##b) / (y##c-y##b); \
}
#define SWAP_X_AND_Y(a, b) \
{\
x = x##a; \
x##a = x##b; \
x##b = x; \
\
x = y##a; \
y##a = y##b; \
y##b = x; \
}
/* /*
* Rasterize a single triangle. * Rasterize a single triangle.
* The triangle is specified by its corner coordinates * The triangle is specified by its corner coordinates
...@@ -41,7 +64,7 @@ void draw_triangle(float x0, float y0, float x1, float y1, float x2, float y2, ...@@ -41,7 +64,7 @@ void draw_triangle(float x0, float y0, float x1, float y1, float x2, float y2,
GLint x, y; GLint x, y;
GLfloat alpha, beta, gamma; GLfloat alpha, beta, gamma;
// Calculate bounding box // calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)), GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2)); x_max = ceil(MAX(x0, x1, x2));
...@@ -79,7 +102,7 @@ void draw_triangle(float x0, float y0, float x1, float y1, float x2, float y2, ...@@ -79,7 +102,7 @@ void draw_triangle(float x0, float y0, float x1, float y1, float x2, float y2,
void draw_triangle_optimized(float x0, float y0, float x1, float y1, void draw_triangle_optimized(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b) float x2, float y2, byte r, byte g, byte b)
{ {
// Calculate bounding box // calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)), GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2)); x_max = ceil(MAX(x0, x1, x2));
...@@ -114,11 +137,9 @@ void draw_triangle_optimized(float x0, float y0, float x1, float y1, ...@@ -114,11 +137,9 @@ void draw_triangle_optimized(float x0, float y0, float x1, float y1,
for( x = x_min; x <= x_max; x++ ) for( x = x_min; x <= x_max; x++ )
{ {
k = alpha * rast_alpha_div; if( (k = alpha * rast_alpha_div) >= 0
l = beta * rast_beta_div; && (l = beta * rast_beta_div) >= 0
m = gamma * rast_gamma_div; && (m = gamma * rast_gamma_div) >= 0
if( k >= 0 && l >= 0 && m >= 0
&& (k > 0 || rast_alpha_offset > 0) && (k > 0 || rast_alpha_offset > 0)
&& (l > 0 || rast_beta_offset > 0) && (l > 0 || rast_beta_offset > 0)
&& (m > 0 || rast_gamma_offset > 0) ) && (m > 0 || rast_gamma_offset > 0) )
...@@ -141,3 +162,155 @@ void draw_triangle_optimized(float x0, float y0, float x1, float y1, ...@@ -141,3 +162,155 @@ void draw_triangle_optimized(float x0, float y0, float x1, float y1,
gamma += Y_DIFF(0, 1); gamma += Y_DIFF(0, 1);
} }
} }
void draw_triangle_optimized_incremental(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b)
{
// calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
GLint x, y;
GLfloat x_start, x_stop;
GLfloat dab, dac, dbc;
// FIXME: temporary initializers
dab = 0;
dac = 0;
dbc = 0;
GLfloat y_middle = 0;
// TODO: implement rast offset
//if( !(r == 0 && g == 255 && b == 0) )
// return;
// If the triangle has two corners at the same y coordinate and the third
// corner is at the top, the variables x_start and x_stop cannot be equal.
//if( ( y0 == y1 && y2 < y0 ) || ( y0 == y2 && y1 < y0 )
// || ( y1 == y2 && y0 < y1 ) )
//{
if( ( y0 == y1 ) || ( y0 == y2 )
|| ( y1 == y2 ) )
{
// TODO: handle each case in the condition above
/*
x_start = floor(MIN(x0, x1, x2));
x_stop = ceil(MAX(x0, x1, x2));
dab = 0;
dac = 0;
dbc = 0;
y_middle = 0;
*/
//printf("printf..\n");
return;
}
else
{
//printf("(%f,%f), (%f,%f), (%f,%f)\n", x0, y0, x1, y1, x2, y2);
// Sort the three points by their x coordinate
/*
if( x0 > x1 )
SWAP_X_AND_Y(0, 1);
if( x1 > x2 )
SWAP_X_AND_Y(1, 2);
if( x0 > x2 )
SWAP_X_AND_Y(0, 2);
assert( x0 < x1 && x1 < x2 && x0 < x2 );
*/
// Sort the three points by their y coordinate
if( y2 > y1 )
{
if( y1 > y0 )
{
//assert(y2 > y1 && y1 > y0); // y2 > y1 > y0
INIT_DELTA_RAST(2, 1, 0);
}
else if( y0 > y1 )
{
//assert(y2 > y1 && y0 > y1); // y2 > y0 > y1
INIT_DELTA_RAST(2, 0, 1);
}
else
{
//assert(y2 > y1 && y0 > y2); // y0 > y2 > y1
INIT_DELTA_RAST(0, 2, 1);
}
}
else if( y2 > y0 )
{
//assert(y1 > y2 && y2 > y0 && y1 > y0 ); // y1 > y2 > y0
INIT_DELTA_RAST(1, 2, 0);
}
else if( y1 > y0 )
{
//assert(y1 > y0 && y0 > y2); // y1 > y0 > y2
INIT_DELTA_RAST(1, 0, 2);
}
else
{
//assert(y0 > y1 && y1 > y2); // y0 > y1 > y2
INIT_DELTA_RAST(0, 1, 2);
}
x_stop = x_start;
}
/*
printf("(%f,%f), (%f,%f), (%f,%f)\n", x0, y0, x1, y1, x2, y2);
printf("x_start: %f, x_stop: %f\n", x_start, x_stop);
printf("x_min: %d, x_max: %d\n", x_min, x_max);
printf("dab: %f, dac: %f, dbc: %f\n", dab, dac, dbc);
printf("r: %d, g: %d, b: %d\n", r, g, b);
puts("--------------------");
*/
// Loop through the triangle's bounding box
for( y = y_min; y <= y_max; y++ )
{
for( x = round(x_start); x <= round(x_stop); x++ )
{
//if( x >= x_min && x <= x_max )
PutPixel(x, y, r, g, b);
}
// Increment
if( dbc > dac )
{
x_stop += y < y_middle ? dbc : dab;
x_start += dac;
}
else
{
x_start += y < y_middle ? dbc : dab;
x_stop += dac;
}
//printf("y: %d => x_start: %f, x_stop: %f\n", y+1, x_start, x_stop);
//assert( x_stop >= x_start && x_start >= x_min && x_stop <= x_max );
}
}
/* Computer Graphics, Assignment, Triangle Rasterization
* Filename ........ trirast.c
* Description ..... Implements triangle rasterization
* Date ............ 11.08.2008
* Created by ...... Paul Melis
*
* Student name .... Sander van Veen
* Student email ... sandervv@gmail.com
* Collegekaart .... 6167969
* Date ............
* Comments ........
*/
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "types.h"
#define MIN(x,y,z) fminf(fminf(x, y), z)
#define MAX(x,y,z) fmaxf(fmaxf(x, y), z)
#define RAST(X,Y,a,b) ((y##a-y##b)*X+(x##b-x##a)*Y+x##a*y##b-x##b*y##a)
/*
* Rasterize a single triangle.
* The triangle is specified by its corner coordinates
* (x0,y0), (x1,y1) and (x2,y2).
* The triangle is drawn in color (r,g,b).
*/
void draw_triangle(float x0, float y0, float x1, float y1, float x2, float y2,
byte r, byte g, byte b)
{
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
GLint x, y;
GLfloat alpha, beta, gamma,
rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1);
for( y = y_min; y <= y_max; y++ )
{
for( x = x_min; x <= x_max; x++ )
{
alpha = RAST(x, y, 1, 2) / rast_alpha;
beta = RAST(x, y, 2, 0) / rast_beta;
gamma = RAST(x, y, 0, 1) / rast_gamma;
//printf("alpha: %f\n", alpha);
//printf("beta: %f\n", beta);
//printf("gamma: %f\n", gamma);
if( alpha >= 0 && beta >= 0 && gamma >= 0
&& ( (alpha > 0 || rast_alpha_offset > 0)
&& (beta > 0 || rast_beta_offset > 0)
&& (gamma > 0 || rast_gamma_offset > 0) ) )
{
PutPixel(x, y, r, g, b);
}
}
}
}
void draw_triangle_optimized(float x0, float y0, float x1, float y1,
float x2, float y2, byte r, byte g, byte b)
{
// Calculate bounding box
GLint x_min = floor(MIN(x0, x1, x2)),
x_max = ceil(MAX(x0, x1, x2));
GLint y_min = floor(MIN(y0, y1, y2)),
y_max = ceil(MAX(y0, y1, y2));
GLint x, y,
x_diff = x_max - x_min + 1;
// Precalculated vars
GLfloat rast_alpha = RAST(x0, y0, 1, 2),
rast_beta = RAST(x1, y1, 2, 0),
rast_gamma = RAST(x2, y2, 0, 1),
rast_alpha_div = 1 / rast_alpha,
rast_beta_div = 1 / rast_beta,
rast_gamma_div = 1 / rast_gamma,
rast_alpha_offset = rast_alpha * RAST(-1, -1, 1, 2),
rast_beta_offset = rast_beta * RAST(-1, -1, 2, 0),
rast_gamma_offset = rast_gamma * RAST(-1, -1, 0, 1),
d_alpha_x = (y1-y2) * rast_alpha_div,
d_beta_x = (y2-y0) * rast_beta_div,
d_gamma_x = (y0-y1) * rast_gamma_div,
d_alpha_y = (x2-x1 - x_diff*(y1-y2)) * rast_alpha_div,
d_beta_y = (x0-x2 - x_diff*(y2-y0)) * rast_beta_div,
d_gamma_y = (x1-x0 - x_diff*(y0-y1)) * rast_gamma_div;
// Initialize incremental multipliers at (0,0)
GLfloat alpha = RAST(x_min, y_min, 1, 2) * rast_alpha_div,
beta = RAST(x_min, y_min, 2, 0) * rast_beta_div,
gamma = RAST(x_min, y_min, 0, 1) * rast_gamma_div;
// Loop through the triangle's bounding box
for( y = y_min; y <= y_max; y++ )
{
for( x = x_min; x <= x_max; x++ )
{
if( alpha >= 0 && beta >= 0 && gamma >= 0
&& ( (alpha > 0 || rast_alpha_offset > 0)
&& (beta > 0 || rast_beta_offset > 0)
&& (gamma > 0 || rast_gamma_offset > 0) ) )
{
PutPixel(x, y, r, g, b);
}
// Increment the multipliers horizontally
alpha += d_alpha_x;
beta += d_beta_x;
gamma += d_gamma_x;
}
// Increment the multipliers vertically
alpha += d_alpha_y;
beta += d_beta_y;
gamma += d_gamma_y;
}
}
\documentclass[a4paper]{article}
\usepackage[english]{babel}
\usepackage{url}
\usepackage{graphicx}
\usepackage{caption}
\begin{document}
\title{Graphics - Practicumopdracht 1}
\author{Sander van Veen \& Tadde\"us Kroes \\ 6167969 \& 6054129 \\
\url{sandervv@gmail.com} \& \url{taddeuskroes@hotmail.com}}
\maketitle
\tableofcontents
\pagebreak
\section{Questions}
\begin{enumerate}
%question 1
\item \emph{What factor(s) inherent in the rasterization algorithm used here influence the speed with which a triangle is drawn?}
%answer
\begin{itemize}
\item Early break points within a loop. We used this in two different cases. First there is the equation $\alpha >= 0$ \footnote[1]{All equations in this question can found in the pseudocode on page 169 in the book.}. This equation is executed along with $\beta >= 0$ and $\gamma >= 0$ after calculating $\alpha$, $\beta$ and $\gamma$. Instead, we could also put the equality check after each calculation, saving us 1 or even 2 (best case) multiplications in each iteration. Line 140-142 in \emph{trirast.c} realize this principle: if \texttt{k} turns out to be less then zero, the condition is false and \texttt{l} is not calculated, etc.. \\
The second case is when the triangle is already being drawn. All horizontal lines in the triangle are closed, so they only end once. So, when the line ends (when the condition is false and drawing is true) the rest of the line can be skipped.
\item Precalculate (parts of) calculations that are used inside a loop. For example: \\ \\
\texttt{
for( b = 0; b = 10; b++ ) \\
\{ \\
a = b / c; \\
\} \\
} \\
can be replaced by: \\ \\
\texttt{
d = 1 / c; \\
for( b = 0; b = 10; b++ ) \\
\{ \\
a = b * d; \\
\}
} \\
\\
because a multiplication costs less time than a division. For example, we used this feature when calculating $\frac{\texttt{alpha}}{f_{12}(x0, y0)}$ (line 140, \emph{trirast.c}).
\end{itemize}
%question 2
\item \emph{The book notes on page 65 at the bottom that “[...] the test is not perfect because the line through the edge may also go through the offscreen point [...]”. How would you handle a situation in which a pixel is exactly on an edge and the edge runs exactly through the offscreen point?}\\
%answer
This can be solved by defining an alternative offscreen point. This second point can be used in cases when the edge runs through the first point.
\end{enumerate}
\pagebreak
\section{Incremental algorithm}
In the optimized code, it is possible to exit the inner loop, when one or more
of the variables $\alpha$, $\beta$ or $\gamma$ is less than zero. This is an
early exit point, because the expression for those variables will return zero
till the end of the inner loop.
\\
\\
We asked ourselves the question: "If it is possible to leave the inner loop
early, is it possible to calculate when the inner loop should be entered?".
\\
\\
Below is a triangle drawn for the points a (2,4), b (0,1) and c (3,0). In order
to draw the triangle in OpenGL, the outer loop will start at $y = 0$ and
increases $y$ with 1 until $y = 4$. If the program starts with $x = 3$ and adds
the delta's of the triangle, it is able to reduce the inner loop.
\begin{center}
\includegraphics[scale=.6]{triangle-plot-1.png}
\captionof{figure}{Example of a triangle with delta's on each side.}
\end{center}
\\
\\
The equation for a delta of a line is: $\Delta ab = (a_x-b_x)/(a_y-b_y)$. In the
triangle shown above, this equation results in the following constants:
$$\Delta ab = (2-0)/(4-2) = 1$$
$$\Delta ac = (2-3)/(4-0) = -1/4$$
$$\Delta bc = (0-3)/(1-0) = -3$$
\\
Given these constants, the inner loop can be constructed using an incremental
algorithm. While $y < b_y$, the start of the inner loop is the previous start
plus $\Delta bc$ and the end of the inner loop is the previous end plus
$\Delta ac$. When $y > b_y$, the start of the inner loop is the previous
start plus $\Delta ab$ and the end of the inner loop is the previous end plus
$\Delta ac$. This algorithm iterates over the drawn pixels only, except for
the pixels on the so-called "triangle edge". Those egde pixels are drawn, if
they succeed in the off-screen point test.
\end{document}
...@@ -361,8 +361,3 @@ main(int argc, char **argv) ...@@ -361,8 +361,3 @@ main(int argc, char **argv)
glutMainLoop(); glutMainLoop();
} }
...@@ -3,13 +3,11 @@ ...@@ -3,13 +3,11 @@
* Description ..... Calculates Plane/Vertex normals * Description ..... Calculates Plane/Vertex normals
* Date ............ 19.08.2008 * Date ............ 19.08.2008
* *
* Student name .... * Student name .... Sander van Veen & Taddeus Kroes
* Student email ... * Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... * Collegekaart .... 6167969 & 6054129
* Date ............ * Date ............ 15.09.2010
* Comments ........ * Comments ........
*
* (always fill in these fields before submitting!!)
*/ */
#include <stdio.h> #include <stdio.h>
...@@ -17,36 +15,201 @@ ...@@ -17,36 +15,201 @@
#include <math.h> #include <math.h>
#include "normals.h" #include "normals.h"
// Calculate flat shading normal for the given polygons. Note that #define EPSILON 1e-6
// you have to set normals for all *vertices* of the polygon, so you
// have to set the normal[] array in the poly struct. #define VECTOR_LENGTH(p) sqrt( p.x*p.x + p.y*p.y + p.z*p.z )
void calcNormalsFlat(polys* list)
/*
* Calculate flat shading normal for the given polygons. Note that
* you have to set normals for all *vertices* of the polygon, so you
* have to set the normal[] array in the poly struct.
*/
void calcNormalsFlat(polys* list)
{ {
poly item; poly *item;
int length = (*list).length; point origin, r1, r2, normal, inside;
for( int i = 0; i < length; i++ ) for( GLint i = 0, len = list->length; i < len; i++ )
{ {
item = (*list).items[i]; item = list->items+i;
// Use the first 3 points of the polygon to determine the plane by
// creating 2 directional vectors. Then, normalize the cross product
// of those vectors to calculate the normal.
origin = item->pts[0];
r1 = substractVectors(item->pts[1], origin);
r2 = substractVectors(item->pts[2], origin);
inside = substractVectors(origin, item->inside);
for( int p = 0; p < item.points; p++ ) normal = normalizeVector(crossProduct(r1, r2));
// Reverse the normal if it is pointing to the inside of the object
if( dotProduct(normal, inside) < 0 )
{ {
normal = scalarMultiply(normal, -1);
} }
// int points; // Set the normal to all points of the polygon
// point pts[MAX_VERTICES]; for( GLint p = 0, l = item->points; p < l; p++ )
// point normal[MAX_VERTICES]; // Vertex normals {
// point pnormal; // Overall polygon normal item->normal[p] = normal;
}
} }
} }
// Calculate normals for Gouraud shading. Again, the data to fill in /*
// is each poly's normal[] array. You can use poly's pnormal field * Calculate normals for Gouraud shading. Again, the data to fill in
// to store temporary values if you like. * is each poly's normal[] array. You can use poly's pnormal field
* to store temporary values if you like.
*/
void calcNormalsGouraud(polys* list) void calcNormalsGouraud(polys* list)
{ {
poly *item, *current;
point normal;
normals *group = NULL, *prev;
// To have some form of shading on the sphere, as shown in // To have some form of shading on the sphere, as shown in
// the assignment, we initally do flat shading here // the assignment, we initally do flat shading here
calcNormalsFlat(list); calcNormalsFlat(list);
// Loop through all polygons, while saving groups of points that have
// (roughly) the same coordinates
for( int i = 0, len = list->length; i < len; i++ )
{
group = createNormals(len, group);
current = list->items+i;
// Check all consecutive polygons
for( int j = i+1; j < len; j++ )
{
item = list->items+j;
// Compare each point in the polygon to the points in the current
for( int k = 0; k < item->points; k++ )
{
int found = 0;
for( int m = 0; m < current->points; m++ )
{
if( equalPoint(item->pts[k], current->pts[m]) )
{
addToNormals(current->normal+m, group);
found = 1;
}
}
if( found )
addToNormals(list->items[j].normal+k, group);
}
}
}
int n = 0;
while( group != NULL )
{
if( group->length )
{
normal = *(group->normal[0]);
for( int i = 1; i < group->length; i++ )
{
normal = addVectors(normal, *(group->normal[i]));
}
normal = normalizeVector(normal);
for( int i = 0; i < group->length; i++ )
{
*(group->normal[i]) = normal;
n++;
}
}
free(group->normal);
prev = group->prev;
free(group);
group = prev;
}
printf("interpolated %d points\n", n);
}
/*
* Helper functions for grouped points
*/
normals* createNormals(int size, normals *prev)
{
// Do not create a new group if the previous group is empty
if( prev != NULL && !prev->length )
return prev;
normals *group = (normals*) malloc(sizeof(normals));
group->normal = (point**) malloc(size * sizeof(point*));
group->length = 0;
group->prev = prev;
return group;
}
void addToNormals(point *p, normals *group)
{
group->normal[group->length++] = p;
}
/*
* Helper functions for points
*/
int equalPoint(point p1, point p2)
{
return fabs(p1.x - p2.x) < EPSILON
&& fabs(p1.y - p2.y) < EPSILON
&& fabs(p1.z - p2.z) < EPSILON;
}
point createPoint(GLdouble x, GLdouble y, GLdouble z)
{
point p = {x, y, z};
return p;
}
/*
* Basic vector operations
*/
point normalizeVector(point p)
{
return scalarMultiply(p, 1 / VECTOR_LENGTH(p));
}
point addVectors(point p1, point p2)
{
return createPoint(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z);
}
point substractVectors(point p1, point p2)
{
return createPoint(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
}
point scalarMultiply(point p, GLdouble scalar)
{
return createPoint(p.x * scalar, p.y * scalar, p.z * scalar);
}
GLdouble dotProduct(point p1, point p2)
{
return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
}
point crossProduct(point p1, point p2)
{
return createPoint( p1.y * p2.z - p1.z * p2.y,
p1.z * p2.x - p1.x * p2.z,
p1.x * p2.y - p1.y * p2.x );
} }
...@@ -9,7 +9,26 @@ ...@@ -9,7 +9,26 @@
#include "polys.h" #include "polys.h"
typedef struct normals
{
point **normal;
int length;
struct normals *prev;
}
normals;
void calcNormalsFlat(polys* list); void calcNormalsFlat(polys* list);
void calcNormalsGouraud(polys* list); void calcNormalsGouraud(polys* list);
normals *createNormals(int size, normals *prev);
void addToNormals(point *p, normals *group);
int equalPoint(point p1, point p2);
point createPoint(GLdouble x, GLdouble y, GLdouble z);
point normalizeVector(point p);
point addVectors(point p1, point p2);
point substractVectors(point p1, point p2);
point scalarMultiply(point p, GLdouble scalar);
GLdouble dotProduct(point p1, point p2);
point crossProduct(point p1, point p2);
#endif #endif
...@@ -4,19 +4,22 @@ ...@@ -4,19 +4,22 @@
* Date ............ 22.07.2009 * Date ............ 22.07.2009
* Created by ...... Paul Melis * Created by ...... Paul Melis
* *
* Student name .... Sander van Veen * Student name .... Sander van Veen & Taddeus Kroes
* Student email ... <sandervv@gmail.com> * Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 * Collegekaart .... 6167969 & 6054129
* Date ............ * Date ............ 02.10.2010
* Comments ........ * Comments ........
*
*
* (always fill in these fields before submitting!!)
*/ */
#include <math.h> #include <math.h>
#include "bezier.h" #include "bezier.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#define INTERSECTION_PRECISION 0.001
/* Calculate the factorial of a number.
*/
int F(int x) { return !x ? 1 : x * F(x-1); } int F(int x) { return !x ? 1 : x * F(x-1); }
...@@ -29,31 +32,24 @@ int F(int x) { return !x ? 1 : x * F(x-1); } ...@@ -29,31 +32,24 @@ int F(int x) { return !x ? 1 : x * F(x-1); }
*/ */
void void
evaluate_bezier_curve(float *x, float *y, control_point p[], int n, float u) evaluate_bezier_curve(float *x, float *y, control_point p[], int num_points, float u)
{ {
int i, n = num_points-1;
float b;
*x = 0.0; *x = 0.0;
*y = 0.0; *y = 0.0;
float u_diff = 1 - u, for( i = 0; i <= n; i++ )
scalar; {
b = ( (float)F(n) / (F(i) * F(n-i)) ) * pow(u, i) * pow(1.0 - u, n - i);
for( int i = 0; i < n; i++ ) *x += b * p[i].x;
{ *y += b * p[i].y;
//printf("p[%d]: (%f, %f), ", i, p[i].x, p[i].y);
scalar = ((float) F(n-1) / (F(i) * F(n-i-1)) ) * powf(u, i) * powf(u_diff, n-i-1);
//printf("scalar: %f\n", scalar);
*x += scalar * p[i].x;
*y += scalar * p[i].y;
//printf("x: %f, y: %f\n", *x, *y);
} }
} }
/* Draw a Bezier curve defined by the control points in p[], which /* Draw a Bezier curve defined by the control points in p[], which
* will contain 'n' points. * will contain 'num_points' points.
* *
* Draw the line segments you compute directly on the screen * Draw the line segments you compute directly on the screen
* as a single GL_LINE_STRIP. This is as simple as using * as a single GL_LINE_STRIP. This is as simple as using
...@@ -76,16 +72,15 @@ evaluate_bezier_curve(float *x, float *y, control_point p[], int n, float u) ...@@ -76,16 +72,15 @@ evaluate_bezier_curve(float *x, float *y, control_point p[], int n, float u)
void void
draw_bezier_curve(int num_segments, control_point p[], int n) draw_bezier_curve(int num_segments, control_point p[], int n)
{ {
float x = 0.0, int i;
y = 0.0; float x, y, u_multiplier = 1.0 / num_segments;
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
for( float u = 0.0; u <= 1; u += 1.0/num_segments ) for( i = 0; i <= num_segments; i++ )
{ {
evaluate_bezier_curve(&x, &y, p, n, u); evaluate_bezier_curve(&x, &y, p, n, i * u_multiplier);
//printf("segments: %d, points: %d\n", num_segments, n); glVertex2f(x, y);
glVertex2f(x, y);
} }
glEnd(); glEnd();
...@@ -100,12 +95,26 @@ draw_bezier_curve(int num_segments, control_point p[], int n) ...@@ -100,12 +95,26 @@ draw_bezier_curve(int num_segments, control_point p[], int n)
int int
intersect_cubic_bezier_curve(float *y, control_point p[], float x) intersect_cubic_bezier_curve(float *y, control_point p[], float x)
{ {
// Newton-Raphson's Method float x_int, y_int, u = 0.5, u_diff = 0.25;
int i = 0, max_i = (int)(1 / INTERSECTION_PRECISION);
// x_1 = x_0 - f(x_0) / f'(x_0)
// x_{n+1} = x_n - f(x_b) / f'(x_n)
while( i++ < max_i )
{
evaluate_bezier_curve(&x_int, &y_int, p, 4, u);
if( fabs(x - x_int) < INTERSECTION_PRECISION )
{
*y = y_int;
return 1;
}
else if( x_int > x )
u -= u_diff;
else
u += u_diff;
u_diff *= 0.5;
}
return 0; return 0;
} }
...@@ -11,6 +11,7 @@ typedef struct control_point ...@@ -11,6 +11,7 @@ typedef struct control_point
} }
control_point; control_point;
int F(int n);
void evaluate_bezier_curve(float *x, float *y, control_point p[], int num_points, float u); void evaluate_bezier_curve(float *x, float *y, control_point p[], int num_points, float u);
void draw_bezier_curve(int num_segments, control_point p[], int num_points); void draw_bezier_curve(int num_segments, control_point p[], int num_points);
int intersect_cubic_bezier_curve(float *y, control_point p[], float x); int intersect_cubic_bezier_curve(float *y, control_point p[], float x);
......
...@@ -24,26 +24,26 @@ ...@@ -24,26 +24,26 @@
control_point control_points[MAX_CONTROL_POINTS] = control_point control_points[MAX_CONTROL_POINTS] =
{ {
{10, 20}, {10, 20},
{50, 80}, {50, 80},
{60, 10}, {60, 10},
{90, 60}, {90, 60},
{80, 80}, {80, 80},
{100, 80}, {100, 80},
}; };
int num_control_points = 4; int num_control_points = 4;
int screen_width, screen_height; int screen_width, screen_height;
float screen_aspect; float screen_aspect;
float world_width, world_height; float world_width, world_height;
int segments = 16; int segments = 16;
int current_control_point = 0; int current_control_point = 0;
// Mouse button currently pressed (and where it was pressed, world coords) // Mouse button currently pressed (and where it was pressed, world coords)
int mouse_mode = -1; int mouse_mode = -1;
float mouse_down_x, mouse_down_y; float mouse_down_x, mouse_down_y;
/* cr, cg, gb is the color of the curve. /* cr, cg, gb is the color of the curve.
pr, pg, pb is the color of the control points pr, pg, pb is the color of the control points
...@@ -52,13 +52,15 @@ static void ...@@ -52,13 +52,15 @@ static void
draw_curve_with_extras(control_point p[], int num_points, draw_curve_with_extras(control_point p[], int num_points,
float cr, float cg, float cb, float pr, float pg, float pb) float cr, float cg, float cb, float pr, float pg, float pb)
{ {
int i; int i;
/* Draw straight lines through control points */ /* Draw straight lines through control points */
glColor3f(0.8, 0.8, 0.8); glColor3f(0.8, 0.8, 0.8);
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
for (i = 0; i < num_points; i++) for (i = 0; i < num_points; i++)
glVertex2f(p[i].x, p[i].y); glVertex2f(p[i].x, p[i].y);
glEnd(); glEnd();
/* Draw the Bezier curve through the points */ /* Draw the Bezier curve through the points */
...@@ -68,14 +70,17 @@ draw_curve_with_extras(control_point p[], int num_points, ...@@ -68,14 +70,17 @@ draw_curve_with_extras(control_point p[], int num_points,
/* Draw dots for the control points */ /* Draw dots for the control points */
glPointSize(3.0); glPointSize(3.0);
glBegin(GL_POINTS); glBegin(GL_POINTS);
for (i = 0; i < num_points; i++) for (i = 0; i < num_points; i++)
{ {
if (i == current_control_point) if (i == current_control_point)
glColor3f(1, 1, 0); glColor3f(1, 1, 0);
else else
glColor3f(pr, pg, pb); glColor3f(pr, pg, pb);
glVertex2f(p[i].x, p[i].y); glVertex2f(p[i].x, p[i].y);
} }
glEnd(); glEnd();
} }
...@@ -85,7 +90,7 @@ draw_handler(void) ...@@ -85,7 +90,7 @@ draw_handler(void)
glClearColor(0.7, 0.7, 0.7, 1); glClearColor(0.7, 0.7, 0.7, 1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
draw_curve_with_extras(control_points, num_control_points, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0); draw_curve_with_extras(control_points, num_control_points, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0);
glutSwapBuffers(); glutSwapBuffers();
} }
...@@ -95,8 +100,8 @@ key_handler(unsigned char key, int x, int y) ...@@ -95,8 +100,8 @@ key_handler(unsigned char key, int x, int y)
{ {
switch (key) { switch (key) {
case 'q': case 'q':
exit(0); exit(0);
// Curve length in control points // Curve length in control points
case '-': case '-':
...@@ -114,24 +119,27 @@ key_handler(unsigned char key, int x, int y) ...@@ -114,24 +119,27 @@ key_handler(unsigned char key, int x, int y)
break; break;
// Nr. of segments to draw // Nr. of segments to draw
case '[': case '[':
segments /= 2; segments /= 2;
if (segments < 1)
segments = 1; if (segments < 1)
printf("Using %d segments to draw Bezier curve\n", segments); segments = 1;
glutPostRedisplay();
break; printf("Using %d segments to draw Bezier curve\n", segments);
case ']': glutPostRedisplay();
break;
case ']':
segments *= 2; segments *= 2;
printf("Using %d segments to draw Bezier curve\n", segments); printf("Using %d segments to draw Bezier curve\n", segments);
glutPostRedisplay(); glutPostRedisplay();
break; break;
// Print control points // Print control points
case 'p': case 'p':
for (int i = 0; i < num_control_points; i++) for (int i = 0; i < num_control_points; i++)
printf("[%d] %3f %.3f\n", i, control_points[i].x, control_points[i].y); printf("[%d] %3f %.3f\n", i, control_points[i].x, control_points[i].y);
break;
break;
} // switch } // switch
} }
......
4 5
0.000000 1.032348
1.000000 1.161391
2.000000 0.000000
3.000000 0.000000
4.000000 0.000000
7.026951 0.000000
8.026952 0.000000
8.026952 2.000000
9.993749 2.000000
10.366405 0.000000
11.387112 0.000000
11.331253 -0.129043
12.269143 -0.110608
14.960552 -0.313391
15.130475 0.700521
18.732819 -0.184348
0.000000 0.000000
1.000000 0.848000
2.000000 0.000000
3.000000 0.000000
4.000000 -0.018435
5.000000 0.000000
6.000000 0.000000
7.020704 -0.165913
6.971096 0.000000
7.985547 0.000000
9.039452 0.000000
11.041406 0.000000
12.020702 0.000000
14.455473 -0.221217
14.463673 -0.073739
17.014450 0.129044
0.000000 0.000000
1.000000 1.216696
2.000000 0.000000
3.000000 0.000000
3.937891 0.000000
5.000000 0.000000
6.000000 0.000000
6.523828 -1.013913
7.378906 -1.013913
8.006250 0.000000
9.068359 0.000000
11.171875 -0.000000
11.979297 0.018435
12.786717 0.129043
17.842583 -0.129044
17.842583 0.737391
0.041406 0.018435
0.979295 1.981565
3.505074 1.963130
4.519527 -0.036870
4.519527 -2.055304
6.037108 -2.000000
6.037108 0.018435
7.037110 0.036870
8.784767 0.000000
9.743361 0.000000
10.716409 0.000000
14.602346 0.000000
15.560940 0.000000
17.560917 0.000000
19.358204 -0.534956
19.441015 2.000000
4 5
0.000000 2.000000
1.469922 2.000000
0.964844 -1.354783
2.296094 0.018435
3.296094 0.018435
5.848828 0.000000
6.848828 0.000000
8.780469 1.815652
10.525782 0.350261
12.581640 -0.000000
13.490624 0.000000
14.022655 0.000000
15.022655 0.000000
17.022652 0.000000
16.000000 0.000000
20.000000 0.000000
0.000000 0.000000
1.000000 1.926261
0.861328 -0.018435
2.151172 0.000000
3.151172 0.000000
4.937891 0.000000
5.937891 0.000000
7.600390 -0.313391
5.937891 0.000000
9.000000 0.000000
10.000000 0.000000
11.000000 0.000000
12.000000 0.000000
14.000000 0.000000
16.000000 0.000000
20.000000 0.000000
0.000000 0.000000
0.979297 1.050782
1.254687 -0.276522
2.171875 -0.018435
3.171875 -0.018435
4.979297 -0.018435
5.979297 -0.018435
6.020704 -0.967652
5.979297 -0.516174
7.012500 -0.000000
7.743358 0.036870
9.144922 -0.497739
10.579687 0.000000
11.469921 0.000000
16.000000 0.000000
20.000000 0.000000
0.000000 0.000000
1.000000 0.977044
2.000000 0.000000
3.000000 0.000000
3.958594 0.000000
3.571485 0.018435
4.592188 0.000000
4.592188 -2.000000
7.035157 -2.718956
7.035157 -0.737391
8.035156 -0.737391
12.594141 -0.774261
13.676953 -0.774261
15.697657 -0.774261
16.000000 -0.792696
20.000000 -0.792696
4 5
0.000000 2.000000
2.254688 2.000000
0.000000 -1.290434
3.000000 0.000000
4.703907 0.000000
4.739063 0.866435
5.772266 1.419478
6.772266 1.419478
6.517579 0.000000
7.517579 0.000000
8.786718 -0.424000
9.240234 0.000000
10.302344 0.000000
10.902736 0.589913
11.461717 -0.387130
18.049612 0.276522
0.000000 1.115131
1.000000 1.115131
0.000000 -0.202783
1.434765 0.018435
2.434766 0.018435
5.000000 0.000000
6.000000 0.000000
7.000000 0.000000
7.937891 -0.184348
9.000000 0.000000
10.186328 0.000000
9.186328 -0.110609
10.186328 -0.110609
10.186328 -0.073740
14.596094 0.276522
15.304296 0.000000
0.000000 1.594435
1.000000 1.557565
0.000000 -0.322435
1.973047 0.000000
3.153126 0.110609
3.929688 -0.092173
5.958594 -0.368695
6.958594 -0.368695
8.000000 0.000000
9.000000 0.000000
11.863282 0.387130
13.732813 -0.055305
14.484375 0.000000
15.962892 0.036870
14.592189 0.000000
15.962892 0.000000
0.000000 2.000000
1.000000 2.000000
0.000000 -0.000000
1.000000 -0.000000
1.000000 0.000000
2.966797 0.018435
2.966797 0.000000
3.883983 0.000000
5.087110 -2.000000
5.087110 -0.018435
6.087110 -0.018435
11.600391 0.000000
12.600391 0.000000
13.842579 0.000000
16.703905 2.000000
20.000000 0.000000
4 5
0.000000 0.000000
1.000000 1.004522
2.000000 1.022957
3.000000 0.000000
4.000000 0.000000
6.213279 0.018435
7.213279 0.018435
8.730859 2.018435
9.426561 1.336348
11.041406 0.000000
12.062109 0.000000
11.958592 -0.092174
12.973046 -0.092174
14.910937 -0.276522
15.813670 0.000000
20.000000 0.000000
0.000000 0.000000
1.000000 0.000000
2.000000 0.000000
3.000000 0.000000
4.020703 1.530087
4.606641 -0.553043
6.000000 0.000000
8.296094 0.350261
7.834375 0.073739
9.414062 0.018435
10.414062 0.018435
10.461719 -0.350261
11.979297 -0.073739
11.979297 -1.050783
14.923049 0.589913
18.037109 0.092174
0.000000 0.000000
1.000000 0.000000
2.000000 0.000000
3.000000 0.000000
4.000000 2.000000
4.730858 -0.516174
6.000000 0.000000
7.062109 -1.013913
7.923438 -0.977044
9.000000 0.000000
9.958593 0.977043
10.006249 -0.368696
11.006249 -0.110609
11.151172 0.202783
13.366405 0.930782
14.824219 0.820174
0.000000 0.000000
1.020703 1.603826
2.000000 0.000000
3.000000 0.000000
4.000000 0.000000
3.488672 0.000000
4.488672 0.000000
5.550781 -2.000000
6.225780 -2.000000
6.225780 -0.055304
7.225780 -0.055304
17.666405 0.000000
18.666407 0.000000
18.666407 2.000000
19.192579 2.000000
20.000000 2.000000
4 5
0.000000 2.000000
2.026953 2.000000
0.020703 -0.239652
2.026953 0.000000
2.675000 0.000000
4.944141 -0.313391
5.068360 0.737391
5.068360 2.737391
6.082813 0.921739
8.469923 0.018435
10.173827 -0.258087
10.233983 -0.129043
11.710155 -0.129044
13.358200 -0.184348
14.633592 -0.239652
16.190639 -0.110609
0.000000 0.884870
1.062109 1.161391
0.985547 -0.811130
2.006250 0.000000
3.006250 0.000000
5.000000 0.000000
6.000000 0.000000
7.000000 0.000000
7.275391 0.000000
8.275392 0.000000
10.621097 -0.516174
10.710155 -0.036870
11.792968 0.000000
14.186328 0.553043
13.370705 0.000000
17.370705 0.000000
0.000000 1.308870
1.000000 1.087652
1.958594 0.018435
2.958594 0.018435
2.958594 -1.981565
4.254687 -0.055304
5.710156 0.018435
6.710156 0.018435
12.026952 0.000000
13.351952 0.000000
14.904686 0.838608
15.277341 0.442435
17.904684 0.000000
18.815626 0.000000
17.946093 0.000000
20.000000 0.000000
0.000000 2.000000
1.000000 2.000000
0.000000 0.000000
1.000000 0.000000
2.000000 0.036870
2.283594 0.018435
2.621094 0.000000
2.621094 -2.000000
3.863281 0.000000
4.863279 0.000000
5.863281 0.000000
15.554689 0.000000
16.554689 0.000000
16.554689 2.000000
20.000000 2.000000
20.000000 0.000000
4 5
0.000000 0.000000
0.000000 2.000000
0.000000 0.737391
4.283594 0.000000
4.283594 2.000000
4.283594 2.000000
6.374609 0.000000
7.623050 0.442435
9.523829 -0.276522
11.000000 0.000000
13.055861 0.313391
13.960547 0.000000
14.960547 0.000000
16.960545 0.000000
16.000000 0.000000
20.000000 0.000000
0.000000 0.000000
0.000000 0.866435
2.000000 0.000000
3.000000 0.000000
4.000000 0.000000
3.269140 0.000000
4.248438 0.000000
4.316797 -0.165913
5.391406 -0.129043
6.412109 0.000000
9.420314 -0.018435
10.942188 0.110608
11.507421 0.000000
15.060155 0.165912
14.269143 -0.073740
15.329295 -0.147478
0.000000 0.000000
0.000000 1.345739
2.000000 0.000000
3.000000 0.000000
4.000000 0.000000
5.000000 0.000000
6.000000 0.000000
7.000000 0.000000
8.000000 0.000000
9.000000 0.000000
10.000000 0.000000
11.000000 0.000000
12.000000 0.000000
14.000000 0.000000
16.000000 0.000000
20.000000 0.000000
0.000000 0.000000
0.000000 2.000000
1.964845 0.000000
3.000000 0.000000
3.000000 -2.000000
4.248437 -1.944696
4.248437 0.000000
5.248437 0.000000
8.041407 0.000000
9.041407 0.000000
10.041407 0.000000
11.000000 0.000000
12.000000 0.000000
12.000000 2.000000
16.000000 0.000000
20.000000 0.000000
4 5
0.000000 0.000000
0.000000 2.000000
0.000000 0.737391
4.283594 0.000000
4.283594 2.000000
4.283594 2.000000
6.374609 0.000000
7.623050 0.442435
9.523829 -0.276522
11.000000 0.000000
13.387112 0.368696
13.960547 0.000000
14.960547 0.000000
16.960545 0.000000
15.912892 1.446957
20.000000 0.000000
0.000000 0.000000
0.000000 0.866435
2.000000 0.000000
3.000000 0.000000
4.000000 0.000000
3.269140 0.000000
4.248438 0.000000
4.316797 -0.165913
5.391406 -0.129043
6.412109 0.000000
9.420314 -0.018435
10.942188 0.110608
11.507421 0.000000
15.267187 0.147477
14.269143 -0.073740
15.329295 -0.147478
0.000000 0.000000
0.000000 1.345739
2.000000 0.000000
3.000000 0.000000
4.000000 0.000000
5.000000 0.000000
6.000000 0.000000
7.000000 0.000000
8.000000 0.000000
9.000000 0.000000
10.000000 0.000000
11.000000 0.000000
12.000000 0.000000
14.000000 0.000000
15.461719 -1.032347
20.000000 0.000000
0.000000 0.000000
0.000000 2.000000
1.964845 0.000000
3.000000 0.000000
3.000000 -2.000000
4.248437 -1.944696
4.248437 0.000000
5.248437 0.000000
8.041407 0.000000
9.041407 0.000000
10.041407 0.000000
11.000000 0.000000
12.000000 0.000000
12.000000 2.000000
16.000000 0.000000
20.000000 0.000000
PROG=opdr1 #
# Sander van Veen (UvA ID: 6167969)
#
PROG=ass1
MKDIR=mkdir MKDIR=mkdir
PACK=tar -jcvf PACK=tar -jcvf
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
for 2009 are defined. for 2009 are defined.
*/ */
/*
* Altered by Sander van Veen (UvA ID: 6167969)
*/
/* interval is a pointer to a struct used by the functions /* interval is a pointer to a struct used by the functions
in the file interval.c. As such it constitutes an opaque data type */ in the file interval.c. As such it constitutes an opaque data type */
...@@ -77,18 +81,14 @@ int delInterval(interval *intervalPtr) ...@@ -77,18 +81,14 @@ int delInterval(interval *intervalPtr)
} }
/* /*
* function: timeInterval
*
* Returns the wall clock time, user CPU time and system CPU time for the * Returns the wall clock time, user CPU time and system CPU time for the
* calling process and its children consumed since the previous call for the * calling process and its children consumed since the previous call for the
* specified interval. * specified interval. Returns zero on success, -1 when an invalid pointer is
* * passed as argument.
* Returns:
* Integer Zero on success, -1 when an invalid pointer is passed as argument.
*/ */
int timeInterval(interval id, double *wct, double *ust, double *syt) int timeInterval(interval id, double *wct, double *ust, double *syt)
{ {
if( !id || wct == NULL || ust == NULL || syt == NULL) if( !id || wct == NULL || ust == NULL || syt == NULL )
return -1; return -1;
struct timeval last_wct = id->last_wct; struct timeval last_wct = id->last_wct;
......
/*
* Sander van Veen (UvA ID: 6167969)
*/
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
...@@ -24,9 +28,6 @@ void consume_time() ...@@ -24,9 +28,6 @@ void consume_time()
s = sqrt(x); s = sqrt(x);
e = pow(10, log10(x)/2); e = pow(10, log10(x)/2);
//if( fmod(x, 1e6) )
// printf("sqrt(%.0f): %f == %f\n", x, s, e);
} }
} }
...@@ -38,7 +39,7 @@ int main (int argc, char **argv) ...@@ -38,7 +39,7 @@ int main (int argc, char **argv)
{ {
interval id = newInterval(); interval id = newInterval();
/* Benchmark the duration of a few system calls using timeInterval. */ // Benchmark the duration of a few system calls using timeInterval.
double wct = 0, double wct = 0,
ust = 0, ust = 0,
...@@ -75,7 +76,7 @@ int main (int argc, char **argv) ...@@ -75,7 +76,7 @@ int main (int argc, char **argv)
if( timeInterval(max_id, &wct, &ust, &syt) ) if( timeInterval(max_id, &wct, &ust, &syt) )
perror("timeInterval() returned a non-zero error code."); perror("timeInterval() returned a non-zero error code.");
fprintf(stderr, "%dx timeInterval took %.3f sec (user: %.3f, sys: %.3f)\n", fprintf(stderr, "%dx timeInterval took %.3f sec (us: %.3f, sy: %.3f)\n",
max, wct, ust, syt); max, wct, ust, syt);
return (EXIT_SUCCESS); return (EXIT_SUCCESS);
......
meten
\ No newline at end of file
/*
* Sander van Veen (UvA ID: 6167969)
*/
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
...@@ -15,8 +19,12 @@ ...@@ -15,8 +19,12 @@
* functies zo snel zijn dat je ze een flink aantal malen moet meten voordat je * functies zo snel zijn dat je ze een flink aantal malen moet meten voordat je
* een betrouwbare meting van met name de CPU-tijd hebt. * een betrouwbare meting van met name de CPU-tijd hebt.
*/ */
static long size = 20e6; static long cur_size = 1e6;
static long stride = 1e5; static long cur_stride = 1;
static long min_size = 1e6;
static long max_size = 128e6;
static long min_stride = 1;
static long max_stride = 2e5;
static long *data; static long *data;
/* /*
...@@ -31,17 +39,28 @@ void time_single_fn(array_fn* fn, double *wct, double *ust, double *syt) ...@@ -31,17 +39,28 @@ void time_single_fn(array_fn* fn, double *wct, double *ust, double *syt)
interval now = newInterval(); interval now = newInterval();
double t_w = 0, t_u = 0, t_s = 0; double t_w = 0, t_u = 0, t_s = 0;
int i = 0;
do do
{ {
(*fn)(data, size, stride); (*fn)(data, cur_size, cur_stride);
timeInterval(now, &t_w, &t_u, &t_s); timeInterval(now, &t_w, &t_u, &t_s);
*wct += t_w; *wct += t_w;
*ust += t_u; *ust += t_u;
*syt += t_s; *syt += t_s;
i++;
} }
while( *wct < 1 ); while( *wct < 1 );
if( i > 1 )
{
*wct /= i;
*ust /= i;
*syt /= i;
}
} }
/* /*
...@@ -69,10 +88,22 @@ void time_single_fn(array_fn* fn, double *wct, double *ust, double *syt) ...@@ -69,10 +88,22 @@ void time_single_fn(array_fn* fn, double *wct, double *ust, double *syt)
void time_fn(array_fn* fn, double *wct, double *ust, double *syt) void time_fn(array_fn* fn, double *wct, double *ust, double *syt)
{ {
time_single_fn(&fillArray, wct, ust, syt); for( cur_size = min_size; cur_size <= max_size; cur_size += cur_size )
{
for( cur_stride = min_stride;
cur_stride <= max_stride;
cur_stride *= 10 )
{
*wct = 0;
*ust = 0;
*syt = 0;
time_single_fn(fn, wct, ust, syt);
printf("size = %ld, stride = %ld, time = %.3f (us: %.3f, sy: %.3f)\n", printf("%9.ld\t%6.ld\t%.3f\t%.3f\t%.3f\n",
size, stride, *wct, *ust, *syt); cur_size, cur_stride, *wct, *ust, *syt);
}
}
} }
/* /*
...@@ -82,20 +113,18 @@ void time_fn(array_fn* fn, double *wct, double *ust, double *syt) ...@@ -82,20 +113,18 @@ void time_fn(array_fn* fn, double *wct, double *ust, double *syt)
*/ */
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
data = malloc( size * sizeof(long *) ); data = malloc(max_size * sizeof(long *));
double wct = 0,
ust = 0,
syt = 0;
double wct = 0, ust = 0, syt = 0;
puts("### fillArray ###"); puts("### fillArray ###");
time_fn(&fillArray, &wct, &ust, &syt); puts("size \tstride\ttime\tuser\tsys");
wct = 0; time_fn(&fillArray, &wct, &ust, &syt);
ust = 0;
syt = 0;
puts("### sumArray ###"); puts("### sumArray ###");
puts("size \tstride\ttime\tuser\tsys");
time_fn(&sumArray, &wct, &ust, &syt); time_fn(&sumArray, &wct, &ust, &syt);
return (EXIT_SUCCESS); return (EXIT_SUCCESS);
......
/*
* Sander van Veen (UvA ID: 6167969)
*/
typedef long(array_fn)(long *array, int size, int stride); typedef long(array_fn)(long *array, int size, int stride);
\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{enumerate}
\usepackage{graphicx}
\usepackage{caption}
\author{Sander van Veen (UvA ID: 6167969) \\ University of Amsterdam}
\title{Operating Systems: Timing}
\begin{document}
\maketitle
\tableofcontents
\pagebreak
\section{Deel A}
\subsection{Vraag en antwoord}
\textit{Probeer door de routines herhaald aan te roepen vanuit een geschikt hoofdprogramma na te gaan hoeveel tijd (CPU en wall-clock) de functie timeInterval gebruikt.} \\
\\
1000000x timeInterval neemt 1.254 sec (us: 0.440, sy: 0.800) in beslag. Dat komt overeen met 1.25 $\mu$ seconde per timeInterval call. \\
\\
\textit{Als die tijden significant zijn, zal je de metingen uit het volgende onderdeel (het meten aan een eenvoudige rekentaak) daarvoor moeten corrigeren. Bespreek je bevindingen in je verslag.} \\
\\
De tijden zijn niet significant ten opzichte van de tijd dat het kost om de ``rekentaak'' uit te voeren. \\
\\
\textit{Probeer (b.v. met je horloge) na te gaan of de gemeten wall-clock time ongeveer overeenkomt met de echte tijd.} \\
\\
De wall-clock time komt overeen met mijn horloge. \\
\\
\textit{Probeer voor zowel voor de echte tijd als voor de CPU tijd na te gaan wat het kleinst meetbare tijdsinterval is, d.w.z. het kleinste tijdsinterval dat een meetresultaat ongelijk aan nul oplevert.} \\
\\
Een clock tick van de cpu is de kleinst meetbare tijdseenheid. Voor een GHz processor is dat 1 miljoenste van een seconde (microseconde).
\\
\\
\textit{Dat kleinst meetbare tijdsinterval bepaalt meteen hoe lang je minimaal moet meten om een nauwkeurigheid van 1 \% te halen. Er zijn ook andere, moeilijker te bepalen effecten die de meetnauwkeurigheid beïnvloeden, zoals variaties in de belasting van de machine. Bespreek in je verslag.} \\
\\
Om de onnauwkeurigheid zo veel mogelijk te beperken, wordt de rekentaak van opdracht 1B voor minimaal een seconde lang uitgevoerd. Vervolgens wordt de totale tijd van de meting gedeeld door het aantal maal dat de taak is uitgevoerd. \\
\\
\textit{Probeer na te gaan of de wall-clock time en de CPU-tijd onderling consistent zijn. Op een machine met één CPU kan je per seconde natuurlijk hooguit één seconde CPU-tijd gebruiken. Bespreek in je verslag.} \\
\\
De wall-clock time en de CPU-tijd zijn onderling consistent, zolang er geen andere taken worden uitgevoerd door de CPU. Anders zullen interrupts het process op pauze zetten en dan wijkt de wall-clock time af van de CPU-time. Er is dan immers minder tijd gerekend dan dat er verstreken is.
\pagebreak
\section{Deel B}
\subsection{De metingen: zonder optimalisatie}
\begin{figure}[h]
\hspace{-1in}
\includegraphics[scale=1.00]{fillArray-plot-no-opt}
\captionof{figure}{fillArray zonder compiler optimalisatie}
\end{figure}
\pagebreak
\begin{figure}[h]
\hspace{-1in}
\includegraphics[scale=1.00]{sumArray-plot-no-opt}
\captionof{figure}{sumArray zonder compiler optimalisatie}
\end{figure}
\pagebreak
\subsection{De metingen: met optimalisatie}
\begin{figure}[h]
\hspace{-1in}
\includegraphics[scale=1.00]{fillArray-plot}
\captionof{figure}{fillArray met $-O3$ compiler optimalisatie}
\end{figure}
\pagebreak
\begin{figure}[h]
\hspace{-1in}
\includegraphics[scale=1.00]{sumArray-plot}
\captionof{figure}{sumArray met $-O3$ compiler optimalisatie}
\end{figure}
\subsection{Analyse en conclusie}
Het is moeilijk om een overtuigende conclusie te trekken uit de gemaakte grafieken. Het is moeilijk omdat de lijnen niet monotoom stijgend zijn; er vindt een schommeling plaats tussen $10^1$ en $10^3$. Dit kan te maken hebben met het branching algoritme van de processor. \\
\\
Wel is er een duidelijke snelheidswinst te zien tussen de door de compiler geoptimaliseerde code (``-O3'') en de niet geoptimaliseerde code (``-O0'') te zien. Ook valt op te merken dat de run time meer uit elkaar gaat de bij geoptimaliseerde code, dan bij de niet geoptimaliseerde code. \\
\\
Bovenstaande experimenten zijn uitgevoerd op een Intel DuoCore E6750 (draaiend op 2.66 GHz) met als besturingssysteem Ubuntu 10.04 en Linux kernel 2.6.32. Tevens beschikt het systeem over 2.0 GiB RAM geheugen.
\end{document}
PROG=ass2 PROG=Opgave2_VanVeen_Kroes
MKDIR=mkdir MKDIR=mkdir
PACK=tar -jcvf PACK=tar -czvf
CC=gcc CC=gcc
LFLAGS=-lm LFLAGS=-lm
CP=cp CP=cp
...@@ -23,14 +23,15 @@ scheduler: scheduler.o mt19937ar.o simul.o mem_alloc.o ...@@ -23,14 +23,15 @@ scheduler: scheduler.o mt19937ar.o simul.o mem_alloc.o
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^ $(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
clean: clean:
rm -f scheduler.o scheduler $(PROG).tbz rm -f scheduler.o scheduler $(PROG).tar.gz
rm -Rf logs/
rm -Rf $(PROG)/ rm -Rf $(PROG)/
tarball: tarball:
$(MAKE) clean $(MAKE) clean
$(MKDIR) $(PROG) $(MKDIR) $(PROG)
$(CP) * $(PROG) || true $(CP) * report/report.pdf $(PROG) 2> /dev/null || true
$(PACK) $(PROG).tbz $(PROG)/* $(PACK) $(PROG).tar.gz $(PROG)/*
$(RM) $(PROG) $(RM) $(PROG)
%.o: %.c %.o: %.c
......
#!/bin/bash #!/bin/bash
if [ ! -d logs/ ]; then
mkdir logs;
echo "Generating log data..."
# compare high-level and cpu schedulers
for hs in {1..4}; do for hs in {1..4}; do
for cs in 1 2 ; do for cs in 0 1 2; do
for cpu in 0.5 0.7 0.8; do echo "hs: $hs, cs: $cs";
for io in 0.5 0.7 0.8; do
for mem in 0.5 0.7 0.8; do # Data for "geheugentoewijzing", "first cycle" and
for ps in 1000; do # "totale verwerkingstijd"
for slice in 100; do for load in $(seq 0.5 0.01 0.99); do
# 0.7 0.7 0.7 1000 4 2 100 cpu=$load;
echo $cpu $io $mem $ps $hs $cs $slice io=$load;
echo $cpu $io $mem $ps $hs $cs $slice|./scheduler \ mem=$load;
&> logs/$cpu-$io-$mem-$ps-$hs-$cs-$slice.log for ps in 1000; do
done for slice in 100; do
done #echo $cpu $io $mem $ps $hs $cs $slice
echo $cpu $io $mem $ps $hs $cs $slice|./scheduler \
&> logs/$cpu-$io-$mem-$ps-$hs-$cs-$slice.log
done done
done done
done done
# Data for "executie-tijd vanaf geheugentoewijzing"
for load in $(seq 0.5 0.01 0.99); do
cpu=$load;
io=$load;
mem=0.70;
for ps in 1000; do
for slice in 100; do
#echo $cpu $io $mem $ps $hs $cs $slice
echo $cpu $io $mem $ps $hs $cs $slice|./scheduler \
&> logs/$cpu-$io-$mem-$ps-$hs-$cs-$slice.log
done
done
done
done done
done done
fi;
for log in high-level first-cycle run-time total-time; do
rm -f logs/$log.log;
done
echo "Parsing log data..."
echo "Generating data for 'wachttijd op geheugentoewijzing'..."
for log in `ls -1 logs/*-0-100.log | sort`; do
mem=`echo $log|cut -d- -f1| sed "s/[^0-9.]//g"`;
hs=`echo $log|cut -d- -f5`;
if [ "$mem" != "`echo $log|cut -d- -f3`" ]; then
continue;
fi
echo -n "$hs $mem " >> logs/high-level.log;
grep -m 1 "Gemiddelde waarde:" $log | cut -d, -f1 | sed -E "s/[^0-9.]//g" \
>> logs/high-level.log;
done
echo "Generating data for 'wachttijd op eerste CPU cycle'..."
for log in `ls -1 logs/*-4-*-100.log | sort`; do
cpu=`echo $log|cut -d- -f1| sed "s/[^0-9.]//g"`;
cs=`echo $log|cut -d- -f6`;
if [ "$cpu" != "`echo $log|cut -d- -f3`" ]; then
continue;
fi
echo -n "$cs $cpu " >> logs/first-cycle.log;
grep -m 2 "Gemiddelde waarde:" $log | cut -d, -f1 | sed -E "s/[^0-9.]//g" \
| tail -n 1 >> logs/first-cycle.log;
done
echo "Generating data for 'executie-tijd vanaf geheugentoewijzing'..."
for log in `ls -1 logs/*-4-*-100.log | sort`; do
cpu=`echo $log|cut -d- -f1| sed "s/[^0-9.]//g"`;
cs=`echo $log|cut -d- -f6`;
if [ "$cpu" == "`echo $log|cut -d- -f3`" ]; then
continue;
fi
echo -n "$cs $cpu " >> logs/run-time.log;
grep -m 3 "Gemiddelde waarde:" $log | cut -d, -f1 | sed -E "s/[^0-9.]//g" \
| tail -n 1 >> logs/run-time.log;
done
echo "Generating data for 'totale verwerkingstijd'..."
for log in `ls -1 logs/*-100.log | sort`; do
load=`echo $log|cut -d- -f1| sed "s/[^0-9.]//g"`;
hs=`echo $log|cut -d- -f5`;
cs=`echo $log|cut -d- -f6`;
if [ "$load" != "`echo $log|cut -d- -f3`" ]; then
continue;
fi
echo -n "$hs $cs $load " >> logs/total-time.log;
grep -m 4 "Gemiddelde waarde:" $log | cut -d, -f1 | sed -E "s/[^0-9.]//g" \
| tail -n 1 >> logs/total-time.log;
done
Simulatie van geheugen-toewijzing en proces-scheduling
Versie 2008-2009
Geef de gewenste CPU belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste IO belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste geheugenbelasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef aantal aan te maken processen:Gelezen waarde: 1000
Gebruikte waarde: 1000
Kies een high-level scheduler:
1. FCFS
2. SJF
3. FCFFS
4. FCFFS (met fairness)
Keuze:
Geef lengte time-slice:
Statistieken op tijdstip = 51623
Opnemen statistieken gestart na 100 aangemaakte processen
op tijdstip 5775.942553
Aantal gevolgde processen: 1000, aantal gereed: 781
Aantal processen wachtend op geheugen: 242
Maximum was: 249, gemiddelde was 144.495063
Gemiddeld gebruik geheugen: 21296 woorden, utilisatie 0.6499
Aantal in de ready queue: 4
Maximum was: 7, gemiddelde was 0.924900
Gebruikte CPU-tijd: 24134, CPU utilisatie: 0.5264
Aantal in de I/O queue: 0
Maximum voor kanaal 0 was: 4, gemiddelde 0.157864
Gebruikte tijd op IO-kanaal 0: 6866, utilisatie: 0.1498
Maximum voor kanaal 1 was: 4, gemiddelde 0.230393
Gebruikte tijd op IO-kanaal 1: 9611, utilisatie: 0.2096
Maximum voor kanaal 2 was: 7, gemiddelde 1.041003
Gebruikte tijd op IO-kanaal 2: 28900, utilisatie: 0.6303
Aantal wachtend op opruimen: 0
Maximum was: 0, gemiddelde was 0.000000
Histogram en statistieken van wachttijd op geheugentoewijzing
over de laatste 781 beeindigde processen
| *
| * * *
27.7 | * * *
| * * * *
| * * * * *
| * * ** * **
| * ** * ** * **
18.4 | *** ** * ** ** **
| **** ** * ** *** * ***
| **** ** * * * ****** * **** *
| **** ** * * ** * ****** * **** * *
|* **** ** * * *** * ****** * **** * *
9.2 |* ******* * * **** ******** ** * ****** * * *
|* ******* * ** ****** * ********* *** * * * ****** * * * *
|** ******** * ********* * *************** * * ******** * * * *
|*********** ************ ***************** * *************** ***
|******************************************** ********************
0.0 |*****************************************************************
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
712 2576 4439 6303 8167 10031 11895
tijdseenheden
Gemiddelde waarde: 6533.3, spreiding: 3477.34
Minimum waarde: 711.6, maximum waarde: 12994.9
-----------------------------------------------------------------
Histogram en statistieken van wachttijd op eerste CPU cycle
over de laatste 781 beeindigde processen
| *
| * *
28.5 | * * *
| * * * *
| * * * * *
| * * ** * *
| * ** * ** * *
19.0 | ** ** * ** ** ***
| **** ** * ** ** * ***
| **** ** * * ****** * ****
| **** ** * * * ****** * **** *
|* **** ** * * *** * ****** * **** * *
9.5 |* ******* * * **** ******** ** * ****** * * *
|* ******* * ** ****** * ********* *** * * * ****** * * * *
|** ******** * ********* * *************** * * ******** * * * *
|*********** ************ ***************** * *************** ***
|******************************************** ********************
0.0 |*****************************************************************
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
712 2576 4439 6303 8167 10031 11895
tijdseenheden
Gemiddelde waarde: 6535.1, spreiding: 3477.58
Minimum waarde: 711.6, maximum waarde: 12994.9
-----------------------------------------------------------------
Histogram en statistieken van executie-tijd vanaf geheugentoewijzing
over de laatste 781 beeindigde processen
| *
| * *
28.5 | * * * *
| * * ** * *
| * * **** * * * *
| **** **** *** ******
| ********** *** *******
19.0 | ***********************
| *********************** *
| ************************ * ** *
|*************************** *****
|*************************** *****
9.5 |*************************** *****
|**********************************
|********************************** **
|************************************* * * * *
|******************************************** * * *
0.0 |******************************************** **** * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
9 83 158 232 307 382 456
tijdseenheden
Gemiddelde waarde: 138.1, spreiding: 82.58
Minimum waarde: 8.7, maximum waarde: 500.2
-----------------------------------------------------------------
Histogram en statistieken van totale verwerkingstijd
over de laatste 781 beeindigde processen
| * * *
| * * * *
23.5 | ** * * * * *
| ** * * ** ** ** *
| ** * * ** ** * ** *
| * ** ** * *** ** * ** *
| * ** ** * *** ** * ** *
15.6 | **** ** * * ****** * ** **
| **** ** * * * ****** * ** **
|* ******* * ** * ****** * ** **
|* ******* * ** * ****** * * ****** *
|* ******* * *** * ******** * ****** * *
7.8 |* ******* * ****** * ********** * * ******* ** * *
|* ********* * ******** ********** *** * ******* *** * *
|*** *********************** *************** ** ************ * *
|******************************************** ** *****************
|*********************************************** *****************
0.0 |*****************************************************************
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
807 2677 4547 6417 8286 10156 12026
tijdseenheden
Gemiddelde waarde: 6671.3, spreiding: 3474.02
Minimum waarde: 807.2, maximum waarde: 13129.2
-----------------------------------------------------------------
Einde statistieken ----------
Simulatie van geheugen-toewijzing en proces-scheduling
Versie 2008-2009
Geef de gewenste CPU belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste IO belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste geheugenbelasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef aantal aan te maken processen:Gelezen waarde: 1000
Gebruikte waarde: 1000
Kies een high-level scheduler:
1. FCFS
2. SJF
3. FCFFS
4. FCFFS (met fairness)
Keuze:
Kies een cpu scheduler:
1. Round robin
2. SJF
Keuze:
Geef lengte time-slice:
Statistieken op tijdstip = 56751
Opnemen statistieken gestart na 100 aangemaakte processen
op tijdstip 5782.799829
Aantal gevolgde processen: 1000, aantal gereed: 926
Aantal processen wachtend op geheugen: 82
Maximum was: 88, gemiddelde was 27.384207
Gemiddeld gebruik geheugen: 24423 woorden, utilisatie 0.7453
Aantal in de ready queue: 1
Maximum was: 8, gemiddelde was 1.343567
Gebruikte CPU-tijd: 32597, CPU utilisatie: 0.6396
Aantal in de I/O queue: 2
Maximum voor kanaal 0 was: 4, gemiddelde 0.168779
Gebruikte tijd op IO-kanaal 0: 7848, utilisatie: 0.1540
Maximum voor kanaal 1 was: 5, gemiddelde 0.246798
Gebruikte tijd op IO-kanaal 1: 10975, utilisatie: 0.2153
Maximum voor kanaal 2 was: 7, gemiddelde 1.177770
Gebruikte tijd op IO-kanaal 2: 32914, utilisatie: 0.6458
Aantal wachtend op opruimen: 0
Maximum was: 0, gemiddelde was 0.000000
Histogram en statistieken van wachttijd op geheugentoewijzing
over de laatste 926 beeindigde processen
|*
|*
589.9 |*
|*
|*
|*
|*
393.3 |*
|*
|*
|*
|*
196.6 |*
|*
|*
|**
|**
0.0 |******************* ** ** * * ** *** * * * * * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 2573 5145 7718 10290 12863 15436
tijdseenheden
Gemiddelde waarde: 556.4, spreiding: 1871.85
Minimum waarde: 0.0, maximum waarde: 16953.6
-----------------------------------------------------------------
Histogram en statistieken van wachttijd op eerste CPU cycle
over de laatste 926 beeindigde processen
|*
|*
584.9 |*
|*
|*
|*
|*
389.9 |*
|*
|*
|*
|*
195.0 |*
|*
|*
|**
|**
0.0 |******************* ** ** * * ** *** * ** * * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 2573 5145 7718 10290 12863 15436
tijdseenheden
Gemiddelde waarde: 560.2, spreiding: 1871.43
Minimum waarde: 0.0, maximum waarde: 16953.6
-----------------------------------------------------------------
Histogram en statistieken van executie-tijd vanaf geheugentoewijzing
over de laatste 926 beeindigde processen
| * * *
| * ** *
33.5 | * * ** *
| * * ** ** *
| * * *** ** ** *
| * ***** ** * *****
| * ** ****** ** * ***** *
22.3 | * ********* ** ******** **
| ***************************
| **************************** *
| **************************** *
| ***************************** *
11.2 | ***************************** **
|*********************************** *
|************************************ * *
|************************************ * * *
|***************************************** * **
0.0 |************************************************* ****** *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
8 92 175 258 341 424 507
tijdseenheden
Gemiddelde waarde: 161.4, spreiding: 90.68
Minimum waarde: 8.5, maximum waarde: 556.4
-----------------------------------------------------------------
Histogram en statistieken van totale verwerkingstijd
over de laatste 926 beeindigde processen
|*
|*
381.3 |*
|*
|*
|*
|**
254.2 |**
|**
|**
|**
|**
127.1 |**
|**
|**
|***
|***
0.0 |********** ******** ** *** * * * * ** * **** * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
10 2589 5168 7746 10325 12903 15482
tijdseenheden
Gemiddelde waarde: 717.7, spreiding: 1863.07
Minimum waarde: 10.2, maximum waarde: 17003.5
-----------------------------------------------------------------
Einde statistieken ----------
Simulatie van geheugen-toewijzing en proces-scheduling
Versie 2008-2009
Geef de gewenste CPU belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste IO belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste geheugenbelasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef aantal aan te maken processen:Gelezen waarde: 1000
Gebruikte waarde: 1000
Kies een high-level scheduler:
1. FCFS
2. SJF
3. FCFFS
4. FCFFS (met fairness)
Keuze:
Kies een cpu scheduler:
1. Round robin
2. SJF
Keuze:
Geef lengte time-slice:
Statistieken op tijdstip = 49644
Opnemen statistieken gestart na 100 aangemaakte processen
op tijdstip 5090.450075
Aantal gevolgde processen: 1000, aantal gereed: 877
Aantal processen wachtend op geheugen: 137
Maximum was: 140, gemiddelde was 91.445832
Gemiddeld gebruik geheugen: 24962 woorden, utilisatie 0.7618
Aantal in de ready queue: 2
Maximum was: 7, gemiddelde was 1.271136
Gebruikte CPU-tijd: 26743, CPU utilisatie: 0.6002
Aantal in de I/O queue: 1
Maximum voor kanaal 0 was: 4, gemiddelde 0.186319
Gebruikte tijd op IO-kanaal 0: 7588, utilisatie: 0.1703
Maximum voor kanaal 1 was: 4, gemiddelde 0.273083
Gebruikte tijd op IO-kanaal 1: 10544, utilisatie: 0.2367
Maximum voor kanaal 2 was: 7, gemiddelde 1.429088
Gebruikte tijd op IO-kanaal 2: 31639, utilisatie: 0.7101
Aantal wachtend op opruimen: 0
Maximum was: 0, gemiddelde was 0.000000
Histogram en statistieken van wachttijd op geheugentoewijzing
over de laatste 877 beeindigde processen
|*
|*
621.8 |*
|*
|*
|*
|*
414.5 |*
|*
|*
|*
|*
207.3 |*
|*
|*
|*
|*
0.0 |************** ***** ** * ** ** **** * * * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 5558 11117 16675 22234 27792 33351
tijdseenheden
Gemiddelde waarde: 1026.7, spreiding: 3964.39
Minimum waarde: 0.0, maximum waarde: 36630.2
-----------------------------------------------------------------
Histogram en statistieken van wachttijd op eerste CPU cycle
over de laatste 877 beeindigde processen
|*
|*
620.1 |*
|*
|*
|*
|*
413.4 |*
|*
|*
|*
|*
206.7 |*
|*
|*
|*
|*
0.0 |************** ***** ** * ** ** **** * * * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 5558 11117 16675 22234 27792 33351
tijdseenheden
Gemiddelde waarde: 1032.6, spreiding: 3964.96
Minimum waarde: 0.0, maximum waarde: 36630.2
-----------------------------------------------------------------
Histogram en statistieken van executie-tijd vanaf geheugentoewijzing
over de laatste 877 beeindigde processen
| *
| * *
29.3 | * **
| * * * * ** *** *
| * * ** * ** * *** * *
| * * ** ***** ***** * *
| ** **** ***** ***** * *
19.6 | ** **************** ****
| ** **************** **** *
| *** ********************** ***
| ************************** *** *
| ***********************************
9.8 | ************************************ *
|************************************** * *
|**************************************** ** * *
|**************************************** **** * *
|***************************************************** * *
0.0 |***************************************************** ***** ** *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
7 80 154 227 300 373 447
tijdseenheden
Gemiddelde waarde: 160.2, spreiding: 91.60
Minimum waarde: 7.1, maximum waarde: 489.8
-----------------------------------------------------------------
Histogram en statistieken van totale verwerkingstijd
over de laatste 877 beeindigde processen
|*
|*
591.6 |*
|*
|*
|*
|*
394.4 |*
|*
|*
|*
|*
197.2 |*
|*
|*
|*
|**
0.0 |************** ***** *** * ** ** **** * * * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
10 5579 11148 16717 22286 27855 33425
tijdseenheden
Gemiddelde waarde: 1186.9, spreiding: 3960.92
Minimum waarde: 10.2, maximum waarde: 36710.3
-----------------------------------------------------------------
Einde statistieken ----------
Simulatie van geheugen-toewijzing en proces-scheduling
Versie 2008-2009
Geef de gewenste CPU belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste IO belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste geheugenbelasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef aantal aan te maken processen:Gelezen waarde: 1000
Gebruikte waarde: 1000
Kies een high-level scheduler:
1. FCFS
2. SJF
3. FCFFS
4. FCFFS (met fairness)
Keuze:
Geef lengte time-slice:
Statistieken op tijdstip = 55061
Opnemen statistieken gestart na 100 aangemaakte processen
op tijdstip 5135.570529
Aantal gevolgde processen: 1000, aantal gereed: 795
Aantal processen wachtend op geheugen: 226
Maximum was: 230, gemiddelde was 128.386650
Gemiddeld gebruik geheugen: 21495 woorden, utilisatie 0.6560
Aantal in de ready queue: 0
Maximum was: 8, gemiddelde was 0.984744
Gebruikte CPU-tijd: 27567, CPU utilisatie: 0.5522
Aantal in de I/O queue: 3
Maximum voor kanaal 0 was: 4, gemiddelde 0.150698
Gebruikte tijd op IO-kanaal 0: 7126, utilisatie: 0.1427
Maximum voor kanaal 1 was: 4, gemiddelde 0.218768
Gebruikte tijd op IO-kanaal 1: 9918, utilisatie: 0.1987
Maximum voor kanaal 2 was: 5, gemiddelde 0.936010
Gebruikte tijd op IO-kanaal 2: 30257, utilisatie: 0.6060
Aantal wachtend op opruimen: 0
Maximum was: 0, gemiddelde was 0.000000
Histogram en statistieken van wachttijd op geheugentoewijzing
over de laatste 795 beeindigde processen
| *
| * *
28.5 | ** *
| ** *
| ** *
| * ** *
| * ** * *
19.0 | * * * *** * *** * *
| * * * * *** * *** * *
| * * ** * **** ** *** * * *
| * * ** * * * **** ** *** *** *
| ** * * * ** * * * ** * ***** ****** **** *
9.5 | ** ** ** * ** ***** ** ** ** ****** ************ *
| *** *** *** ****** ***** ***** *** ******* * ************ *
| ******* *** ******* ***** ****** *** ********* ***************
|************************** ********************* ****************
|************************** ********************* ****************
0.0 |*****************************************************************
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
825 2405 3986 5566 7147 8727 10308
tijdseenheden
Gemiddelde waarde: 6491.2, spreiding: 3033.20
Minimum waarde: 824.7, maximum waarde: 11240.4
-----------------------------------------------------------------
Histogram en statistieken van wachttijd op eerste CPU cycle
over de laatste 795 beeindigde processen
| *
| *
29.3 | ** *
| ** *
| ** *
| ** *
| * ** * * *
19.6 | * *** * * * * *
| * * * * *** * * * * *
| * * ** * **** ** *** * * *
| ** * * ** * * * **** ** *** * * *
| ** * * * ** * * * ** * ***** ****** *** *
9.8 | ** ** ** * ** ***** ** ** ** ****** ************ *
| ****** *** ****** ***** ***** *** ******* * ************ *
| ******* *** ******* ***** ****** *** ********* ***************
|************************** ********************* ****************
|************************** ********************* ****************
0.0 |*****************************************************************
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
825 2406 3986 5567 7148 8729 10310
tijdseenheden
Gemiddelde waarde: 6493.3, spreiding: 3033.45
Minimum waarde: 824.7, maximum waarde: 11242.5
-----------------------------------------------------------------
Histogram en statistieken van executie-tijd vanaf geheugentoewijzing
over de laatste 795 beeindigde processen
| * *
| * * *
29.3 | ** * * * *
| *** ** * * **
| * *** ** * * **
| * * *** ** *** **
| * ********* *** ** *
19.6 | * ********* **** ** **
| *************** **** ** ****
| ****************************
| **************************** *
|* ***************************** *
9.8 |******************************** *
|********************************** **
|************************************** **
|************************************** ** *
|********************************************* * * *
0.0 |*********************************************** ***** * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
7 80 153 226 299 372 446
tijdseenheden
Gemiddelde waarde: 143.8, spreiding: 79.77
Minimum waarde: 7.0, maximum waarde: 488.7
-----------------------------------------------------------------
Histogram en statistieken van totale verwerkingstijd
over de laatste 795 beeindigde processen
| *
| *
27.7 | *
| *
| *
| *** * *
| *** ****
18.4 | * *** **** * *
| * * * * **** **** * ***
| ** * ** * ** * **** ******* ***
| ** ** * ** * ** ** * **** ******* ***
| *** ** * * ** * ** ** * **** ******* ***
9.2 | *** ** ** * ***** * ** ** * * ****** *************
| *** ******* ******** ** ***** **** ******* ***************
| *** ******* ************ ***** ****** ******* ***************
| *********** ****************** *************** ***************
|*****************************************************************
0.0 |*****************************************************************
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
913 2519 4125 5731 7337 8943 10549
tijdseenheden
Gemiddelde waarde: 6635.0, spreiding: 3036.06
Minimum waarde: 913.0, maximum waarde: 11496.6
-----------------------------------------------------------------
Einde statistieken ----------
Simulatie van geheugen-toewijzing en proces-scheduling
Versie 2008-2009
Geef de gewenste CPU belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste IO belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste geheugenbelasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef aantal aan te maken processen:Gelezen waarde: 1000
Gebruikte waarde: 1000
Kies een high-level scheduler:
1. FCFS
2. SJF
3. FCFFS
4. FCFFS (met fairness)
Keuze:
Statistieken op tijdstip = 60257
Opnemen statistieken gestart na 100 aangemaakte processen
op tijdstip 4913.335557
Aantal gevolgde processen: 1000, aantal gereed: 951
Aantal processen wachtend op geheugen: 62
Maximum was: 62, gemiddelde was 40.179773
Gemiddeld gebruik geheugen: 24226 woorden, utilisatie 0.7393
Aantal in de ready queue: 0
Maximum was: 7, gemiddelde was 1.336520
Gebruikte CPU-tijd: 35878, CPU utilisatie: 0.6483
Aantal in de I/O queue: 4
Maximum voor kanaal 0 was: 3, gemiddelde 0.161759
Gebruikte tijd op IO-kanaal 0: 8318, utilisatie: 0.1503
Maximum voor kanaal 1 was: 4, gemiddelde 0.239034
Gebruikte tijd op IO-kanaal 1: 11578, utilisatie: 0.2092
Maximum voor kanaal 2 was: 6, gemiddelde 1.114462
Gebruikte tijd op IO-kanaal 2: 35272, utilisatie: 0.6373
Aantal wachtend op opruimen: 0
Maximum was: 0, gemiddelde was 0.000000
Histogram en statistieken van wachttijd op geheugentoewijzing
over de laatste 951 beeindigde processen
|*
|*
665.4 |*
|*
|*
|*
|*
443.6 |*
|*
|*
|*
|*
221.8 |*
|*
|*
|*
|*
0.0 |********* * ** ******** * * ******* ****** ** *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 4196 8393 12589 16785 20982 25178
tijdseenheden
Gemiddelde waarde: 1465.7, spreiding: 4862.88
Minimum waarde: 0.0, maximum waarde: 27653.9
-----------------------------------------------------------------
Histogram en statistieken van wachttijd op eerste CPU cycle
over de laatste 951 beeindigde processen
|*
|*
665.4 |*
|*
|*
|*
|*
443.6 |*
|*
|*
|*
|*
221.8 |*
|*
|*
|*
|*
0.0 |********* * ** ******** * * ******* ****** ** *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 4196 8393 12589 16785 20982 25178
tijdseenheden
Gemiddelde waarde: 1468.7, spreiding: 4862.24
Minimum waarde: 0.0, maximum waarde: 27653.9
-----------------------------------------------------------------
Histogram en statistieken van executie-tijd vanaf geheugentoewijzing
over de laatste 951 beeindigde processen
| *
| * *
37.7 | * *
| * * * * *
| ** * ******* *
| ** ********** *
| ** *********** * *
25.1 | * *** *********** * ***
| ***** *************** ****
| ********************* ****
| ********************** ****
| ***************************
12.6 |* *************************** * **
|******************************* ** *
|******************************* ** **
|**************************************
|**************************************** * *
0.0 |*********************************************** *** **
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
8 98 189 279 369 459 550
tijdseenheden
Gemiddelde waarde: 166.4, spreiding: 93.92
Minimum waarde: 8.2, maximum waarde: 602.9
-----------------------------------------------------------------
Histogram en statistieken van totale verwerkingstijd
over de laatste 951 beeindigde processen
|*
|*
619.3 |*
|*
|*
|*
|*
412.8 |*
|*
|*
|*
|*
206.4 |*
|*
|*
|**
|**
0.0 |********** * ** ******** * * ************** ** *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
9 4221 8433 12645 16857 21069 25281
tijdseenheden
Gemiddelde waarde: 1632.1, spreiding: 4846.69
Minimum waarde: 9.2, maximum waarde: 27766.5
-----------------------------------------------------------------
Einde statistieken ----------
Simulatie van geheugen-toewijzing en proces-scheduling
Versie 2008-2009
Geef de gewenste CPU belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste IO belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste geheugenbelasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef aantal aan te maken processen:Gelezen waarde: 1000
Gebruikte waarde: 1000
Kies een high-level scheduler:
1. FCFS
2. SJF
3. FCFFS
4. FCFFS (met fairness)
Keuze:
Statistieken op tijdstip = 53937
Opnemen statistieken gestart na 100 aangemaakte processen
op tijdstip 5281.293008
Aantal gevolgde processen: 1000, aantal gereed: 958
Aantal processen wachtend op geheugen: 47
Maximum was: 54, gemiddelde was 37.104698
Gemiddeld gebruik geheugen: 28781 woorden, utilisatie 0.8783
Aantal in de ready queue: 2
Maximum was: 9, gemiddelde was 1.534977
Gebruikte CPU-tijd: 32540, CPU utilisatie: 0.6688
Aantal in de I/O queue: 1
Maximum voor kanaal 0 was: 4, gemiddelde 0.182796
Gebruikte tijd op IO-kanaal 0: 8210, utilisatie: 0.1687
Maximum voor kanaal 1 was: 4, gemiddelde 0.267750
Gebruikte tijd op IO-kanaal 1: 11390, utilisatie: 0.2341
Maximum voor kanaal 2 was: 7, gemiddelde 1.439546
Gebruikte tijd op IO-kanaal 2: 34190, utilisatie: 0.7027
Aantal wachtend op opruimen: 0
Maximum was: 0, gemiddelde was 0.000000
Histogram en statistieken van wachttijd op geheugentoewijzing
over de laatste 958 beeindigde processen
|*
|*
305.9 |*
|*
|*
|*
|*
203.9 |*
|*
|*
|*
|*
102.0 |*
|**
|**
|****
|***** *
0.0 |***************************************** *** ***** ******* ****
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 1738 3475 5213 6951 8688 10426
tijdseenheden
Gemiddelde waarde: 1695.8, spreiding: 2484.31
Minimum waarde: 0.0, maximum waarde: 11451.1
-----------------------------------------------------------------
Histogram en statistieken van wachttijd op eerste CPU cycle
over de laatste 958 beeindigde processen
|*
|*
305.9 |*
|*
|*
|*
|*
203.9 |*
|*
|*
|*
|*
102.0 |*
|*
|**
|****
|*******
0.0 |***************************************** *** ***** ******* ****
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 1738 3476 5213 6951 8689 10427
tijdseenheden
Gemiddelde waarde: 1699.1, spreiding: 2483.30
Minimum waarde: 0.0, maximum waarde: 11451.8
-----------------------------------------------------------------
Histogram en statistieken van executie-tijd vanaf geheugentoewijzing
over de laatste 958 beeindigde processen
| *
| * * * *
38.5 | * * * *
| ******** ***
| ***************
| ***************
| * ***************
25.7 | ****************** **
| **********************
| ***********************
|* ***********************
|*************************
12.8 |************************* *
|************************** *
|****************************** ****
|*********************************** **
|**************************************** * *
0.0 |******************************************** * **** ***
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
6 113 219 326 433 540 647
tijdseenheden
Gemiddelde waarde: 173.8, spreiding: 106.23
Minimum waarde: 5.8, maximum waarde: 709.9
-----------------------------------------------------------------
Histogram en statistieken van totale verwerkingstijd
over de laatste 958 beeindigde processen
| *
| *
155.0 | *
|**
|**
|**
|**
103.4 |**
|***
|***
|***
|***
51.7 |***
|***** *
|***** *
|******* *
|************ ****** *
0.0 |***************************************** ** *************** ***
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
6 1757 3508 5259 7010 8761 10512
tijdseenheden
Gemiddelde waarde: 1869.6, spreiding: 2465.56
Minimum waarde: 5.8, maximum waarde: 11545.3
-----------------------------------------------------------------
Einde statistieken ----------
Simulatie van geheugen-toewijzing en proces-scheduling
Versie 2008-2009
Geef de gewenste CPU belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste IO belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste geheugenbelasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef aantal aan te maken processen:Gelezen waarde: 1000
Gebruikte waarde: 1000
Kies een high-level scheduler:
1. FCFS
2. SJF
3. FCFFS
4. FCFFS (met fairness)
Keuze:
Statistieken op tijdstip = 49775
Opnemen statistieken gestart na 100 aangemaakte processen
op tijdstip 4078.000711
Aantal gevolgde processen: 1000, aantal gereed: 901
Aantal processen wachtend op geheugen: 120
Maximum was: 120, gemiddelde was 64.674641
Gemiddeld gebruik geheugen: 24509 woorden, utilisatie 0.7480
Aantal in de ready queue: 1
Maximum was: 8, gemiddelde was 1.358981
Gebruikte CPU-tijd: 28127, CPU utilisatie: 0.6155
Aantal in de I/O queue: 2
Maximum voor kanaal 0 was: 4, gemiddelde 0.184592
Gebruikte tijd op IO-kanaal 0: 7636, utilisatie: 0.1671
Maximum voor kanaal 1 was: 4, gemiddelde 0.268890
Gebruikte tijd op IO-kanaal 1: 10607, utilisatie: 0.2321
Maximum voor kanaal 2 was: 8, gemiddelde 1.456389
Gebruikte tijd op IO-kanaal 2: 32125, utilisatie: 0.7030
Aantal wachtend op opruimen: 0
Maximum was: 0, gemiddelde was 0.000000
Histogram en statistieken van wachttijd op geheugentoewijzing
over de laatste 901 beeindigde processen
|*
|*
565.6 |*
|*
|*
|*
|*
377.1 |*
|*
|*
|*
|*
188.5 |*
|*
|*
|**
|**
0.0 |********************** * * * ** ***** ** * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 2231 4462 6693 8924 11155 13386
tijdseenheden
Gemiddelde waarde: 444.9, spreiding: 1390.02
Minimum waarde: 0.0, maximum waarde: 14702.6
-----------------------------------------------------------------
Histogram en statistieken van wachttijd op eerste CPU cycle
over de laatste 901 beeindigde processen
|*
|*
563.1 |*
|*
|*
|*
|*
375.4 |*
|*
|*
|*
|*
187.7 |*
|*
|*
|**
|**
0.0 |********************** * * * ** ***** ** * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 2231 4462 6693 8924 11155 13386
tijdseenheden
Gemiddelde waarde: 448.0, spreiding: 1389.26
Minimum waarde: 0.0, maximum waarde: 14702.6
-----------------------------------------------------------------
Histogram en statistieken van executie-tijd vanaf geheugentoewijzing
over de laatste 901 beeindigde processen
| * * *
| * * * * *
33.5 | * * * * * *
| * * * *** *
| * ******** *
| * ******** ***
| * * **************
22.3 | * *** ***************
| ** ******************** *
| *********************** *
| ************************ *
|* ************************ * * *
11.2 |* ************************ *** * * *
|******************************* * * * **
|********************************* *** ** *
|************************************* ** * **
|******************************************** ***
0.0 |*************************************************** * **** * * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
9 93 177 262 346 430 514
tijdseenheden
Gemiddelde waarde: 166.0, spreiding: 98.91
Minimum waarde: 9.2, maximum waarde: 563.7
-----------------------------------------------------------------
Histogram en statistieken van totale verwerkingstijd
over de laatste 901 beeindigde processen
|*
|*
305.9 |**
|**
|**
|**
|**
203.9 |**
|**
|**
|**
|**
102.0 |***
|***
|***
|***
|***
0.0 |********** *********** *** *** **** * ** * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
12 2245 4478 6712 8945 11179 13412
tijdseenheden
Gemiddelde waarde: 610.8, spreiding: 1380.79
Minimum waarde: 11.6, maximum waarde: 14729.7
-----------------------------------------------------------------
Einde statistieken ----------
Simulatie van geheugen-toewijzing en proces-scheduling
Versie 2008-2009
Geef de gewenste CPU belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste IO belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste geheugenbelasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef aantal aan te maken processen:Gelezen waarde: 1000
Gebruikte waarde: 1000
Kies een high-level scheduler:
1. FCFS
2. SJF
3. FCFFS
4. FCFFS (met fairness)
Keuze:
Statistieken op tijdstip = 54450
Opnemen statistieken gestart na 100 aangemaakte processen
op tijdstip 4721.563969
Aantal gevolgde processen: 1000, aantal gereed: 925
Aantal processen wachtend op geheugen: 94
Maximum was: 106, gemiddelde was 58.268396
Gemiddeld gebruik geheugen: 24580 woorden, utilisatie 0.7501
Aantal in de ready queue: 2
Maximum was: 10, gemiddelde was 1.407064
Gebruikte CPU-tijd: 31721, CPU utilisatie: 0.6379
Aantal in de I/O queue: 0
Maximum voor kanaal 0 was: 5, gemiddelde 0.179842
Gebruikte tijd op IO-kanaal 0: 8144, utilisatie: 0.1638
Maximum voor kanaal 1 was: 5, gemiddelde 0.261435
Gebruikte tijd op IO-kanaal 1: 11219, utilisatie: 0.2256
Maximum voor kanaal 2 was: 9, gemiddelde 1.437796
Gebruikte tijd op IO-kanaal 2: 34128, utilisatie: 0.6863
Aantal wachtend op opruimen: 0
Maximum was: 0, gemiddelde was 0.000000
Histogram en statistieken van wachttijd op geheugentoewijzing
over de laatste 925 beeindigde processen
|*
|*
652.0 |*
|*
|*
|*
|*
434.6 |*
|*
|*
|*
|*
217.3 |*
|*
|*
|*
|**
0.0 |**************** * *** * * * * * * * * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 4291 8582 12872 17163 21454 25745
tijdseenheden
Gemiddelde waarde: 612.8, spreiding: 2331.04
Minimum waarde: 0.0, maximum waarde: 28276.4
-----------------------------------------------------------------
Histogram en statistieken van wachttijd op eerste CPU cycle
over de laatste 925 beeindigde processen
|*
|*
651.1 |*
|*
|*
|*
|*
434.1 |*
|*
|*
|*
|*
217.0 |*
|*
|*
|*
|**
0.0 |**************** * *** * * * * * * * * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 4291 8582 12872 17163 21454 25745
tijdseenheden
Gemiddelde waarde: 616.4, spreiding: 2330.38
Minimum waarde: 0.0, maximum waarde: 28276.4
-----------------------------------------------------------------
Histogram en statistieken van executie-tijd vanaf geheugentoewijzing
over de laatste 925 beeindigde processen
| * *
| ** * * *
31.8 | *** * * * **
| *** * * ****
| * *** ** ****** **
| * ***** ** ****** **
| * * ***** ** ****** ***
21.2 | ** * ***** ********* ***
| **** * *************** *** *
| **** ***************** ***** *
| **** *************************
| ******************************* *
10.6 | ******************************* * *
|******************************** ** *
|************************************ * *
|************************************** ***** *
|******************************************** *** * * **
0.0 |************************************************** *** ******* **
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
8 93 178 263 347 432 517
tijdseenheden
Gemiddelde waarde: 177.8, spreiding: 103.24
Minimum waarde: 7.9, maximum waarde: 567.3
-----------------------------------------------------------------
Histogram en statistieken van totale verwerkingstijd
over de laatste 925 beeindigde processen
|*
|*
566.5 |*
|*
|*
|*
|*
377.7 |*
|*
|*
|*
|*
188.8 |*
|*
|**
|**
|**
0.0 |**************** * *** * * * * * * * * *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
9 4334 8659 12984 17309 21634 25959
tijdseenheden
Gemiddelde waarde: 790.6, spreiding: 2321.43
Minimum waarde: 9.3, maximum waarde: 28510.8
-----------------------------------------------------------------
Einde statistieken ----------
Simulatie van geheugen-toewijzing en proces-scheduling
Versie 2008-2009
Geef de gewenste CPU belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste IO belasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef de gewenste geheugenbelasting (tussen 0 en 1):Gelezen waarde: 0.700000
Geef aantal aan te maken processen:Gelezen waarde: 1000
Gebruikte waarde: 1000
Geef lengte time-slice: Statistieken op tijdstip = 53018
Opnemen statistieken gestart na 100 aangemaakte processen
op tijdstip 5238.252081
Aantal gevolgde processen: 1000, aantal gereed: 914
Aantal processen wachtend op geheugen: 98
Maximum was: 111, gemiddelde was 46.264024
Gemiddeld gebruik geheugen: 27442 woorden, utilisatie 0.8375
Aantal in de ready queue: 2
Maximum was: 7, gemiddelde was 1.199458
Gebruikte CPU-tijd: 31094, CPU utilisatie: 0.6508
Aantal in de I/O queue: 0
Maximum voor kanaal 0 was: 4, gemiddelde 0.177745
Gebruikte tijd op IO-kanaal 0: 7878, utilisatie: 0.1649
Maximum voor kanaal 1 was: 6, gemiddelde 0.258180
Gebruikte tijd op IO-kanaal 1: 10921, utilisatie: 0.2286
Maximum voor kanaal 2 was: 8, gemiddelde 1.400437
Gebruikte tijd op IO-kanaal 2: 32941, utilisatie: 0.6894
Aantal wachtend op opruimen: 0
Maximum was: 0, gemiddelde was 0.000000
Histogram en statistieken van wachttijd op geheugentoewijzing
over de laatste 914 beeindigde processen
|*
|*
72.1 |*
|*
|*
|*
|*
48.0 |*
|**
|**
|** *
|***** * *
24.0 |******* *** *
|*********** ******* * *
|*********** ******** *****
|***************************** *** ***
|****************************************** * * *
0.0 |************************************************************** *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 1208 2417 3625 4834 6042 7250
tijdseenheden
Gemiddelde waarde: 2091.2, spreiding: 1787.17
Minimum waarde: 0.0, maximum waarde: 7963.3
-----------------------------------------------------------------
Histogram en statistieken van wachttijd op eerste CPU cycle
over de laatste 914 beeindigde processen
|*
|*
70.4 |*
|*
|*
|*
|*
46.9 |**
|**
|**
|*** * *
|***** * *
23.5 |******* *** * * *
|*********** ******* * *
|*********** ******** *****
|***************************** *** ***
|****************************************** * * * *
0.0 |************************************************************** *
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
0 1208 2417 3625 4834 6042 7250
tijdseenheden
Gemiddelde waarde: 2091.8, spreiding: 1787.16
Minimum waarde: 0.0, maximum waarde: 7963.3
-----------------------------------------------------------------
Histogram en statistieken van executie-tijd vanaf geheugentoewijzing
over de laatste 914 beeindigde processen
| *
| *
27.7 | * **
| * * * **
| * * *** ***
| * * * ** **** **** *
| * ** *** ** ****** ***** *
18.4 | * ** *** *********** ****** **
| * ************************* ****
| ** ************************** *****
|* ***************************** ***** *
|*************************************** *
9.2 |**************************************** * ** *
|******************************************* *****
|************************************************* **
|*****************************************************
|***************************************************** ** * **
0.0 |******************************************************** ** **
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
8 73 138 202 267 332 397
tijdseenheden
Gemiddelde waarde: 159.2, spreiding: 90.28
Minimum waarde: 7.9, maximum waarde: 435.3
-----------------------------------------------------------------
Histogram en statistieken van totale verwerkingstijd
over de laatste 914 beeindigde processen
| *
| *
46.9 | *
| *
| *
| **
| ****
31.3 | **** **
| ***** ** *
| ****** *** * *
|************* *** * *
|************* ***** * * **
15.6 |************* ****** *** **
|********************* ****** * *
|********************* ************* *
|********************* ******************
|****************************************** * * *** * **
0.0 |*****************************************************************
|----|----|----|----|----|----|----|----|----|----|----|----|----|
| | | | | | |
25 1255 2486 3716 4946 6176 7406
tijdseenheden
Gemiddelde waarde: 2250.4, spreiding: 1776.43
Minimum waarde: 25.3, maximum waarde: 8132.0
-----------------------------------------------------------------
Einde statistieken ----------
En nu de `eigen informatie-routine'
Gegevens over de nog wachtende processen
Er staan nog 98 processen op geheugen te wachten
De oudste daarvan wacht al 7008 tijdseenheden en vraagt 21252 woorden aan
Gemiddeld vragen de processen 15203 woorden aan
en staan ze 2989 tijdseenheden te wachten
De grootste aanvraag is: 24576 en de kleinste: 693
Einde programma
\relax
\@writefile{toc}{\contentsline {section}{\numberline {1}Inleiding}{2}}
This is pdfTeX, Version 3.1415926-1.40.10 (TeX Live 2009/Debian) (format=pdflatex 2010.8.26) 12 OCT 2010 17:52
entering extended mode
restricted \write18 enabled.
%&-line parsing enabled.
**report.tex
(./report.tex
LaTeX2e <2009/09/24>
Babel <v3.8l> and hyphenation patterns for english, usenglishmax, dumylang, noh
yphenation, dutch, loaded.
(/usr/share/texmf-texlive/tex/latex/base/article.cls
Document Class: article 2007/10/19 v1.4h Standard LaTeX document class
(/usr/share/texmf-texlive/tex/latex/base/size10.clo
File: size10.clo 2007/10/19 v1.4h Standard LaTeX file (size option)
)
\c@part=\count79
\c@section=\count80
\c@subsection=\count81
\c@subsubsection=\count82
\c@paragraph=\count83
\c@subparagraph=\count84
\c@figure=\count85
\c@table=\count86
\abovecaptionskip=\skip41
\belowcaptionskip=\skip42
\bibindent=\dimen102
)
(/usr/share/texmf-texlive/tex/latex/base/inputenc.sty
Package: inputenc 2008/03/30 v1.1d Input encoding file
\inpenc@prehook=\toks14
\inpenc@posthook=\toks15
(/usr/share/texmf-texlive/tex/latex/base/latin1.def
File: latin1.def 2008/03/30 v1.1d Input encoding file
))
(/usr/share/texmf-texlive/tex/latex/amsmath/amsmath.sty
Package: amsmath 2000/07/18 v2.13 AMS math features
\@mathmargin=\skip43
For additional information on amsmath, use the `?' option.
(/usr/share/texmf-texlive/tex/latex/amsmath/amstext.sty
Package: amstext 2000/06/29 v2.01
(/usr/share/texmf-texlive/tex/latex/amsmath/amsgen.sty
File: amsgen.sty 1999/11/30 v2.0
\@emptytoks=\toks16
\ex@=\dimen103
))
(/usr/share/texmf-texlive/tex/latex/amsmath/amsbsy.sty
Package: amsbsy 1999/11/29 v1.2d
\pmbraise@=\dimen104
)
(/usr/share/texmf-texlive/tex/latex/amsmath/amsopn.sty
Package: amsopn 1999/12/14 v2.01 operator names
)
\inf@bad=\count87
LaTeX Info: Redefining \frac on input line 211.
\uproot@=\count88
\leftroot@=\count89
LaTeX Info: Redefining \overline on input line 307.
\classnum@=\count90
\DOTSCASE@=\count91
LaTeX Info: Redefining \ldots on input line 379.
LaTeX Info: Redefining \dots on input line 382.
LaTeX Info: Redefining \cdots on input line 467.
\Mathstrutbox@=\box26
\strutbox@=\box27
\big@size=\dimen105
LaTeX Font Info: Redeclaring font encoding OML on input line 567.
LaTeX Font Info: Redeclaring font encoding OMS on input line 568.
\macc@depth=\count92
\c@MaxMatrixCols=\count93
\dotsspace@=\muskip10
\c@parentequation=\count94
\dspbrk@lvl=\count95
\tag@help=\toks17
\row@=\count96
\column@=\count97
\maxfields@=\count98
\andhelp@=\toks18
\eqnshift@=\dimen106
\alignsep@=\dimen107
\tagshift@=\dimen108
\tagwidth@=\dimen109
\totwidth@=\dimen110
\lineht@=\dimen111
\@envbody=\toks19
\multlinegap=\skip44
\multlinetaggap=\skip45
\mathdisplay@stack=\toks20
LaTeX Info: Redefining \[ on input line 2666.
LaTeX Info: Redefining \] on input line 2667.
)
(/usr/share/texmf-texlive/tex/latex/amsfonts/amsfonts.sty
Package: amsfonts 2009/06/22 v3.00 Basic AMSFonts support
\symAMSa=\mathgroup4
\symAMSb=\mathgroup5
LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
(Font) U/euf/m/n --> U/euf/b/n on input line 96.
)
(/usr/share/texmf-texlive/tex/latex/amsfonts/amssymb.sty
Package: amssymb 2009/06/22 v3.00
)
(/usr/share/texmf-texlive/tex/latex/tools/enumerate.sty
Package: enumerate 1999/03/05 v3.00 enumerate extensions (DPC)
\@enLab=\toks21
)
(/usr/share/texmf-texlive/tex/latex/listings/listings.sty
(/usr/share/texmf-texlive/tex/latex/graphics/keyval.sty
Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
\KV@toks@=\toks22
)
\lst@mode=\count99
\lst@gtempboxa=\box28
\lst@token=\toks23
\lst@length=\count100
\lst@currlwidth=\dimen112
\lst@column=\count101
\lst@pos=\count102
\lst@lostspace=\dimen113
\lst@width=\dimen114
\lst@newlines=\count103
\lst@lineno=\count104
\lst@maxwidth=\dimen115
(/usr/share/texmf-texlive/tex/latex/listings/lstmisc.sty
File: lstmisc.sty 2007/02/22 1.4 (Carsten Heinz)
\c@lstnumber=\count105
\lst@skipnumbers=\count106
\lst@framebox=\box29
)
(/usr/share/texmf-texlive/tex/latex/listings/listings.cfg
File: listings.cfg 2007/02/22 1.4 listings configuration
))
Package: listings 2007/02/22 1.4 (Carsten Heinz)
(/usr/share/texmf-texlive/tex/latex/ltxmisc/url.sty
\Urlmuskip=\muskip11
Package: url 2006/04/12 ver 3.3 Verb mode for urls, etc.
)
(/usr/share/texmf-texlive/tex/latex/float/float.sty
Package: float 2001/11/08 v1.3d Float enhancements (AL)
\c@float@type=\count107
\float@exts=\toks24
\float@box=\box30
\@float@everytoks=\toks25
\@floatcapt=\box31
) (./report.aux)
\openout1 = `report.aux'.
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 15.
LaTeX Font Info: ... okay on input line 15.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 15.
LaTeX Font Info: ... okay on input line 15.
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 15.
LaTeX Font Info: ... okay on input line 15.
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 15.
LaTeX Font Info: ... okay on input line 15.
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 15.
LaTeX Font Info: ... okay on input line 15.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 15.
LaTeX Font Info: ... okay on input line 15.
\c@lstlisting=\count108
LaTeX Font Info: Try loading font information for U+msa on input line 17.
(/usr/share/texmf-texlive/tex/latex/amsfonts/umsa.fd
File: umsa.fd 2009/06/22 v3.00 AMS symbols A
)
LaTeX Font Info: Try loading font information for U+msb on input line 17.
(/usr/share/texmf-texlive/tex/latex/amsfonts/umsb.fd
File: umsb.fd 2009/06/22 v3.00 AMS symbols B
) (./report.toc)
\tf@toc=\write3
\openout3 = `report.toc'.
[1
{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2] (./report.aux) )
Here is how much of TeX's memory you used:
2672 strings out of 495006
34111 string characters out of 1181410
84332 words of memory out of 3000000
5855 multiletter control sequences out of 15000+50000
9497 words of font info for 36 fonts, out of 3000000 for 9000
68 hyphenation exceptions out of 8191
27i,7n,32p,223b,219s stack positions out of 5000i,500n,10000p,200000b,50000s
</usr/
share/texmf-texlive/fonts/type1/public/amsfonts/cm/cmbx10.pfb></usr/share/texmf
-texlive/fonts/type1/public/amsfonts/cm/cmbx12.pfb></usr/share/texmf-texlive/fo
nts/type1/public/amsfonts/cm/cmr10.pfb></usr/share/texmf-texlive/fonts/type1/pu
blic/amsfonts/cm/cmr12.pfb></usr/share/texmf-texlive/fonts/type1/public/amsfont
s/cm/cmr17.pfb>
Output written on report.pdf (2 pages, 65119 bytes).
PDF statistics:
29 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 500000)
1 words of extra memory for PDF output out of 10000 (max. 10000000)
...@@ -9,7 +9,29 @@ ...@@ -9,7 +9,29 @@
\usepackage{url} \usepackage{url}
\usepackage{float} \usepackage{float}
\title{Operating systems opdracht 2: Scheduler} \usepackage[dutch]{babel}
\usepackage{listings}
\lstset{
language=C,
numbers=left,
numberstyle=\footnotesize,
stepnumber=1,
numbersep=5pt,
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=4,
captionpos=t,
breaklines=false
}
% dot graphs
\usepackage{dot2texi}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows}
\title{Operating systems opdracht 2: Scheduling}
\author{Sander van Veen \& Tadde\"us Kroes} \author{Sander van Veen \& Tadde\"us Kroes}
\begin{document} \begin{document}
...@@ -22,28 +44,388 @@ ...@@ -22,28 +44,388 @@
\section{Inleiding} \section{Inleiding}
In deze opdracht hebben wij high-level scheduler en een CPU scheduler gemaakt Scheduling heeft te maken met het toewijzen van hulpbronnen aan processen. Als
voor het toewijzen van hulpbronnen aan processen. We hebben onderscheid gemaakt dit op een ``eerlijke'' en effici\"ente manier gebeurt kan dit een grote
tussen vier high-level schedulers: positieve invloed hebben op de systeemprestaties. \\
\\
In deze opdracht hebben wij enkele resource schedulers gemaakt,
hierbij is onderscheid gemaakt tussen drie soorten hulpbronnen:
\begin{enumerate}
\item \textbf{Geheugen}. De high-level scheduler bepaald in welke volgorde
de processen geheugen krijgen toegewezen.
\item \textbf{CPU}. De CPU-scheduler regelt hierbij op welk moment en hoe
lang een proces gebruik mag maken van de processor.
\item Drie \textbf{I/O devices}. De scheduling hiervan wordt geregeld door
de aangeleverde simulator. Via de shell van de scheduler kunnen de te
simuleren load-factoren worden ingesteld.
\end{enumerate}
\subsection{High-level schedulers}
\noindent De high-level schedulers die we hebben getest zijn:
\begin{enumerate}
\item \textbf{First come, first served (FCFS)} \\
Aan het proces dat als eerste aankomt (en dus al het langste wacht)
wordt als eerste geheugen toegewezen.
\item \textbf{Shortest job first (SJF)} \\
Het proces wat het minste geheugen nodig heeft, krijgt voorrang.
\item \textbf{First come and fit, first served (FCFFS)} \\
Alle processen worden doorlopen op volgorde van aankomsttijd. Als
er voldoende geheugen beschikbaar is, wordt dat toegewezen.
\item \textbf{Shortest job first (SJF) met fairness} \\
Het proces wat de minste hulpbronnen nodig heeft, krijgt voorrang
tenzij er een proces is met een threshold groter dan een van tevoren
gespecificeerde constante. De threshold van een proces wordt opgehoogd
wanneer het proces wel het minste geheugen nodig heeft, maar niet meer
in het geheugen past. Hierdoor krijgt een proces wat al een aantal
keren onfortuinlijk niet in het geheugen heeft gepast, voorrang op een
eventueel ``korter'' proces, waardoor starvation\footnote{Starvation
betekent dat een proces nooit wordt afgehandeld, omdat er geen
hulpbronnen voor beschikbaar komen. Zie ook: \\
\url{http://en.wikipedia.org/wiki/Starvation_(computing)}} wordt
voorkomen.
\end{enumerate}
\subsection{CPU schedulers}
Ook hebben we verschillende CPU schedulers:
\begin{enumerate}
\item \textbf{First come, first served (FCFS, is aangeleverd)} \\
Aan het proces dat als eerste aankomt, wordt als eerste CPU-tijd
toegewezen. Het volgende proces is pas aan de beurt als het huidige
proces is afgehandeld.
\item \textbf{Round robin (RR)} \\
Hierbij wordt de rij in circulaire volgorde doorlopen, waarbij telkens
een vast aantal tijdseenheden aan CPU-tijd wordt toegewezen aan een
proces. Hierdoor zullen kortere processen altijd in minder tijd
worden afgerond.
\item \textbf{Longest job first (LJF)} \\
De processen die het meeste geheugen nodig hebben, zullen
waarschijnlijk ook de meeste CPU-tijd nodig hebben. Deze processen
krijgen daarom als eerste tijdsintervallen CPU-tijd toegewezen. Dit
zou als gevolg moeten hebben dat de processen min of meer tegelijk
worden afgerond.
\end{enumerate}
\section{Testomgeving (simulator)}
Door de practicumleiding is een simulatieprogramma aangeleverd, dat wij hier
kort zullen toelichten.
\subsection{Procesrijen}
\begin{itemize}
\item \texttt{new\_proc}: \\
Hier worden nieuwe processen geplaatst door de simulator.
\item \texttt{ready\_proc}: \\
Wanneer er geheugen wordt toegewezen aan een proces in de
\texttt{new\_proc} rij, wordt dit proces naar de \texttt{ready\_proc}
rij verplaatst.
\item \texttt{io\_proc}: \\
Wanneer aan een proces een I/O-device wordt toegewezen, wordt dit
proces in de \texttt{io\_proc} rij geplaatst. Wanneer de tijd met het
I/O-device erop zit, wordt het proces weer terug in de
\texttt{ready\_proc} geplaatst.
\item \texttt{defunct\_proc}: \\
Be\"eindigde processen worden in deze rij geplaatst, zodat ze kunnen
worden opgeruimd m.b.v. \texttt{rm\_process}.
\end{itemize}
\begin{figure}[H]
\begin{dot2tex}[dot,options=-tmath --autosize --cache]
digraph G {
rankdir=LR;
start [shape="none",label=""];
start -> q_{new};
q_{new} -> q_{ready} [label="NewProcess"];
q_{ready} -> q_{io} [label="I/O"];
q_{ready} -> q_{defunct} [label="Finish"];
q_{ready} -> q_{ready} [label="Time"];
q_{io} -> q_{ready} [label="Ready"];
}
\end{dot2tex}
\caption{De transities tussen de procesrijen. De knopen zijn de procesrijen,
bij de pijlen staan de namen van de events waardoor de transities
tussen de desbetreffende rijen plaatsvinden.}
\end{figure}
\subsection{Discrete Event Simulation}
Bij een Discrete Event Simulation (DES)\footnote{Zie ook:
\url{http://en.wikipedia.org/wiki/Discrete_Event_Simulation}} worden events in
chronologische volgorde afgehandeld. De event handler in deze simulator is de
functie \texttt{schedule} (\emph{scheduler.c}). Deze handler kan de
volgende soorten events afhandelen:
\begin{itemize}
\item \texttt{NewProcess\_event}: \\
Er is een nieuw proces in de \texttt{new\_proc} rij bijgeplaatst door
de simulator.
\item \texttt{Time\_event}: \\
Het lopende proces heeft zijn time-slice opgebruikt. Wordt gegenereerd
wanneer \texttt{set\_slice} is aangeroepen.
\item \texttt{Ready\_event}: \\
Een proces is klaar met I/O en is weer achteraan de
\texttt{ready\_proc} rij geplaatst.
\item \texttt{IO\_event}: \\
Het lopende proces gaat I/O doen en is achteraan de \texttt{io\_proc}
rij geplaatst.
\item \texttt{Finish\_event}: \\
Het lopende proces is be\"eindigd en in de \texttt{defunct\_proc} rij
geplaatst.
\end{itemize}
\subsection{Implementatie van de schedulers}
Elke scheduler is ge\"implementeerd in een aparte functie, met de functienaam
\texttt{GiveMemory\_\{type\}} (high-level scheduler) of \texttt{CPU\_\{type\}}
(CPU-scheduler). Het programma vraagt de gebruiker om de high-level en de
CPU-scheduler te kiezen via \texttt{stdin}. Aan de hand van deze invoer worden
twee functie-pointers toegewezen aan de functies die corresponderen met de
gekozen schedulers. Deze pointers worden aangeroepen tijdens de executie van
het programma. \\
\indent De constante \texttt{FAIRNESS\_THRESHOLD} hebben we op 3 bepaald. We ondervonden namelijk dat bij hogere en lagere waarden de resultaten minder goed waren.
\subsection{Variabelen}
De simulator heeft zes variabelen die worden ingevoerd via \texttt{stdin}:
\begin{enumerate}
\item De load van het geheugen die niet wordt veroorzaakt door de
gesimuleerde processen.
\item De load op de processor die niet wordt veroorzaakt door de
gesimuleerde processen.
\item De load op de I/O-devices die niet wordt veroorzaakt door de
gesimuleerde processen.
\item Het aantal te simuleren processen.
\item De high-level scheduler die moet worden gebruikt (vier keuzes).
\item De CPU-scheduler die moet worden gebruikt (drie keuzes).
\item Het aantal tijdseenheden van de time-slice voor de CPU scheduler.
\end{enumerate}
\subsection{Statistieken}
Aan de hand van bovengenoemde variabelen geeft de simulator een aantal
statistieken terug. Deze statistieken bevatten de volgende informatie:
\begin{itemize}
\item Het aantal be\"eindigde processen.
\item De gebruikte tijd op en utilisatie van de CPU.
\item De gebruikte tijd op en utilisatie van alle I/O-devices.
\item De wachttijd op geheugentoewijzing van alle processen (grafiek).
\item De wachttijd op eerste CPU cycle van alle processen (grafiek).
\item De executietijd vanaf geheugentoewijzing van alle processen (grafiek).
\item De totale verwerkingstijd van alle processen (grafiek).
\end{itemize}
\section{Experiment}
We hebben ervoor gekozen om de volgende punten te vergelijken met behulp van
grafieken:
\begin{enumerate}
\item \emph{Verschil tussen high-level schedulers:} \\
De wachttijd op geheugentoewijzing wordt bepaald door de gebruikte
high-lever scheduler en door de load op het systeem. Daarom zetten we
oplopende waarden van de load factor uit tegen de gemiddelde wachttijd
op geheugentoewijzing.
\item \emph{Fairness van de CPU-schedulers:} \\
We zetten de gemiddelde wachttijd tot de eerste CPU cycle per proces
uit tegen de load factor van het systeem. Hiermee kunnen we zien welke
CPU-scheduler het ``eerlijkst'' is. Dat wil zeggen dat elk proces
binnen een acceptabele tijd zijn eerste CPU cycle krijgt toegewezen.
Hierdoor is te zien wanneer starvation optreedt.
\item \emph{Verschil in executietijd tussen de CPU-schedulers:} \\
We zetten de gemiddelde executietijd vanaf geheugentoewijzing uit
tegen de CPU- en I/O-load factor (de memory load houden we hetzelfde,
deze heeft immers alleen effect op de tijd v\'o\'or
geheugentoewijzing).
\item \emph{Verschillende combinaties van high-level en CPU-schedulers:} \\
We willen weten of het uitmaakt in welke combinatie de high-level en
CPU-schedulers worden gebruikt. Hiervoor zetten we de gemiddelde
totale executietijd uit tegen de load-factor van het systeem.
\end{enumerate}
\pagebreak
\section{Resultaten}
Met behulp van een bash-script (\emph{benchmark.bash}; zie appendix B.2)
hebben we data gegenereerd en verzameld voor verschillende variabelen. Deze
data hebben we in grafieken omgezet, waarbij we observaties hebben gedaan. \\
\\
Vanaf een load-factor van 0.55 is er pas een significant verschil te zien
tussen de verschillende schedulers. Daarom hebben we de metingen met een
lagere load factor dan 0.50 weggelaten uit de grafiek. \\
\\
Merk ook op dat er geen data is gegenereerd voor een load factor van 1.00.
De simulation accepteert dit niet als waarde, omdat processen dan geen
hulpbronnen kunnen krijgen toegewezen.
\subsection{Verschil tussen high-level schedulers}
\begin{figure}[H]
\hspace{-.82in}
\includegraphics{../plot/high-level.pdf}
\caption{Gemiddelde tijd voor de geheugentoewijzingen voor elke high-level
schedulers onder verschillende load-factoren.}
\end{figure}
We zien dat FCFS slechte resultaten boekt, naarmate er minder hulpbronnen
beschikbaar zijn (hogere load factor). FCFFS heeft hier minder last van, waar
we bij SJF (zowel met als zonder fairness) vrijwel geen stijging zien vanaf
een load factor van circa 0.65. \\
\\
We zien bij SJF zonder fairness echter wel twee grote pieken, waar deze pieken
bij SJF met fairness ontbreken. Het gebruik van de fairness threshold zorgt
ervoor dat processen die deze pieken veroorzaken wel binnen acceptabele tijd
geheugen krijgen toegewezen.
\subsection{Fairness van de CPU-schedulers}
\begin{figure}[H]
\hspace{-.75in}
\includegraphics{../plot/first-cycle.pdf}
\caption{Gemiddelde wachttijd op eerste CPU cycle voor elke
CPU-schedulers onder verschillende load-factoren.}
\end{figure}
LJF heeft meer en hogere pieken dan FCFS en RR. Dit verklaren wij door
het feit dat bij LJF korte processen niet snel aan de beurt komen, als
er langere processen blijven worden toegevoegd. Hoewel RR in principe
de ``eerlijkste'' is, lijkt FCFS gemiddeld een lagere wachttijd te hebben.
Het zou echter kunnen dat de grafiek er anders uit zal zien, bij een andere
time-slice en een andere hoeveelheid processen. Wij hebben deze variabelen
echter gelijk gehouden omdat we de resultaten in dezelfde omgeving willen
vergelijken. \\
\\
Het is te verwachten dat FCFS hier het beste resultaat behaald, omdat een
proces nooit naar achteren in de wachtrij wordt geplaatst. Bij LJF zien
wij een grotere spreiding. Dit komt doordat sommige (langere) processen
snel aan de beurt komen en andere (kortere) processen juist later. Bij RR
wordt elke proces na elke time-slice achteraan de wachtrij geplaatst, dus
is het logisch dat hier de minste spreiding is te zien.\\
\\
Het valt ons op dat rond een load factor van 0.65 de wachttijd voor de
eerste CPU cycle een piek lijkt te hebben. Wij kunnen hier geen andere
verklaring voor bedenken dan dat de aangeleverde simulator geen volledig
willekeurige processenreeks nabootst. We zouden namelijk verwachten dat
er geen daling in de grafiek voorkomt, want als er meer load op de CPU staat,
verwachten wij dat de gemiddelde wachttijd hoger is. Dit vermoeden wordt
versterkt door het feit dat we in de grafiek van het vorige resultaat ook
een afwijking rond deze load factor zien. Daarom zullen we in de volgende
resultaten de afwijkingen rond deze load factor negeren.
\subsection{Verschil in executietijd tussen de CPU-schedulers}
\begin{figure}[H]
\hspace{-.68in}
\includegraphics{../plot/run-time.pdf}
\caption{Gemiddelde executietijd vanaf geheugentoewijzing voor elke
CPU-schedulers onder verschillende I/O- en CPU load-factoren, met constante
memory load-factor.}
\end{figure}
Hoewel in kleine mate, zien we dat FCFS de langste gemiddelde executie-tijd
heeft. Dit is dan ook het minst slimme algoritme. We zien ook dat de
variatie in de load factor geen verschil maakt in executietijd tussen de
verschillende CPU-schedulers. \\
\\
Tenslotte observeren we dat LJF het beste lijkt te presteren. Dit zou kunnen
betekenen dat de meeste processen rond de gemiddelde executietijd zitten.
\subsection{Verschillende combinaties van high-level en CPU-schedulers}
\begin{figure}[H]
\hspace{-.82in}
\includegraphics{../plot/total-time-1.pdf}
\caption{Gemiddelde totale verwerkingstijd voor elke high-level en
CPU-schedulers onder verschillende load-factoren.}
\end{figure}
Het eerste wat ons opvalt is dat de grafiek dezelfde vorm heeft als de grafiek
van het eerste resultaat (de high-level schedulers). \\
\\
Bij alledrie de lijngroepen zien we dat bij RR scheduling de combinatie het
meest stabiel vari\"eert van de groep, bij verschillende load-factoren. \\
\\
Om het verschil tussen SJF met en zonder fairness beter te kunnen zien, hebben
we het onderste gedeelte van de grafiek voor beide types apart getoond in de
volgende grafieken. \\
\\
Meegenomen het feit dat we de afwijking in de grafiek rond de load-factor van
0.65 negeren, zien we dat de load-factor weinig effect heeft op de executietijd
bij een SJF high-level scheduler (zowel met als zonder fairness).
\pagebreak
\begin{figure}[H]
\hspace{-.85in}
\includegraphics{../plot/total-time-2.pdf}
\caption{Gemiddelde totale verwerkingstijd voor de SJF high-level scheduler
en elke CPU-scheduler onder verschillende load-factoren.}
\end{figure}
\begin{figure}[H]
\vspace{-0.5cm}
\hspace{-.85in}
\includegraphics{../plot/total-time-3.pdf}
\caption{Gemiddelde totale verwerkingstijd voor de SJF high-level scheduler
met fairness en elke CPU-scheduler onder verschillende load-factoren.}
\end{figure}
\noindent
We zien duidelijk dat SJF met fairness minder hoge pieken heeft en dat het
verschil tussen de CPU-schedulers kleiner is. Dit kunnen we verklaren doordat
er zonder fairness meer uitschieters zijn wat betreft wachttijd op
geheugentoewijzing. De fairness threshold voorkomt deze uitschieters.
\section{Conclusies}
Uit bovenstaande waarnemingen hebben wij de volgende conclusies getrokken.
\subsection{High-level scheduling}
\begin{enumerate} \begin{enumerate}
\item First come, first served (FCFS) \item Shortest job first (SJF) is de beste keuze voor een high-level
\item Shortest job first (SJF) scheduler, omdat deze nauwelijks afhankelijk is van de load-factor
\item First come and fit, first served (FCFFS) van het gehele systeem. Het gebruik van FCFS is een slecht idee,
\item Shortest job first (SJF) met fairness zeker bij een hoge load-factor.
\item Het toevoegen van een fairness threshold zorgt voor een stabielere
wachttijd op geheugentoewijzing.
\item De keuze van een high-level scheduler heeft de meeste invloed op
de totale performance van procesafhandeling.
\end{enumerate} \end{enumerate}
en drie CPU schedulers:
\subsection{CPU-scheduling}
\begin{enumerate} \begin{enumerate}
\item First come, first served (FCFS; is aangeleverd) \item RR is het ``eerlijkst'', want deze scheduler maakt geen onderscheid
\item Round robin (RR) tussen processen in de volgorde van het toewijzen van hulpbronnen.
\item Longest job first (LJF) \item Longest job first (LJF) is gevoelig voor starvation. Dit komt door
het feit dat korte processen niet gegarandeerd aan de beurt komen,
doordat het voor kan komen dat er langere processen bij blijven
komen.
\item Het verschil in load-factor brengt geen verschil in effici\"entie
tussen de CPU-schedulers.
\end{enumerate} \end{enumerate}
\section{Simulator} \subsection{Eindconclusie}
Shortest job first is de beste keuze van de geteste high-level schedulers.
Het toevoegen van een fairness threshold helpt hier bij om uitschieters te
voorkomen. Deze high-level scheduler met een Round Robin CPU-scheduler is
het beste van de geteste combinaties.
\section{Opmerkingen}
Het gebruik van processtatistieken (denk aan het aantal gebruikte
CPU time-slices en een nice-factor) zou kunnen bijdragen aan een
beter presterende scheduler.
\pagebreak
\appendix
\section{Code}
\subsection{scheduler.c}
\lstinputlisting{../scheduler.c}
\pagebreak
Door de practicumleiding is een simulatie programma aangeleverd, die wij hier \subsection{benchmark.bash}
kort toe zullen lichten.
\subsection{} \lstinputlisting[tabsize=2]{../benchmark.bash}
\end{document} \end{document}
\contentsline {section}{\numberline {1}Inleiding}{2}
...@@ -6,18 +6,18 @@ ...@@ -6,18 +6,18 @@
#include "mem_alloc.h" #include "mem_alloc.h"
/* /*
* This file contains a bare bones skeleton for the scheduler hl_handlertion * This file contains a bare bones skeleton for the scheduler function
* for the second assignment for the OSN course of the 2005 fall semester. * for the second assignment for the OSN course of the 2005 fall semester.
* Author: Sander van Veen (6167969)
* *
* G.D. van Albada * G.D. van Albada
* Section Computational Science * Section Computational Science
* Universiteit van Amsterdam * Universiteit van Amsterdam
*
* Date:
* October 23, 2003
* Modified:
* September 29, 2005 * September 29, 2005
*
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 & 6054129
* Date ............ 10.10.2010
*/ */
#define FAIRNESS_THRESHOLD 3 #define FAIRNESS_THRESHOLD 3
...@@ -30,7 +30,7 @@ static double timeslice = 100; ...@@ -30,7 +30,7 @@ static double timeslice = 100;
static long memory[MEM_SIZE]; static long memory[MEM_SIZE];
/* /*
* The actual CPU scheduler is implemented here * Round Robin CPU scheduler
*/ */
static void CPU_scheduler_RR() static void CPU_scheduler_RR()
{ {
...@@ -41,26 +41,33 @@ static void CPU_scheduler_RR() ...@@ -41,26 +41,33 @@ static void CPU_scheduler_RR()
enqueue_back(&ready_proc, dequeue(&ready_proc)); enqueue_back(&ready_proc, dequeue(&ready_proc));
} }
static void CPU_scheduler_SJF() /*
* Longest job first CPU scheduler
*/
static void CPU_scheduler_LJF()
{ {
if( !ready_proc ) if( !ready_proc )
return; return;
pcb *proc, *proc_min; pcb *proc, *proc_max;
for( proc = proc_min = ready_proc; proc; proc = proc->next ) // Find the longest job and put it at the front of the queue
for( proc = proc_max = ready_proc; proc; proc = proc->next )
{ {
if( proc->MEM_need < proc_min->MEM_need ) if( proc->MEM_need > proc_max->MEM_need )
proc_min = proc; proc_max = proc;
} }
set_slice(timeslice); set_slice(timeslice);
enqueue_front(&ready_proc, remove_from_queue(&ready_proc, proc_min)); enqueue_front(&ready_proc, remove_from_queue(&ready_proc, proc_max));
} }
/*
* First come, first serve CPU scheduler
*/
static void CPU_scheduler_FCFS() static void CPU_scheduler_FCFS()
{ {
// This function is implemented by the simulator.
} }
/* /*
...@@ -90,17 +97,24 @@ static void GiveMemory_FCFFS() ...@@ -90,17 +97,24 @@ static void GiveMemory_FCFFS()
} }
} }
/*
* First come, first serve high-level scheduler
*/
static void GiveMemory_FCFS() static void GiveMemory_FCFS()
{ {
int index; int index;
if( new_proc && (index = mem_get(new_proc->MEM_need)) >= 0 ) // Assign all available memory to the first processes in the queue
while( new_proc && (index = mem_get(new_proc->MEM_need)) >= 0 )
{ {
new_proc->MEM_base = index; new_proc->MEM_base = index;
enqueue_back(&ready_proc, dequeue(&new_proc)); enqueue_back(&ready_proc, dequeue(&new_proc));
} }
} }
/*
* Shortest job first high-level scheduler
*/
static void GiveMemory_SJF() static void GiveMemory_SJF()
{ {
int index; int index;
...@@ -109,12 +123,14 @@ static void GiveMemory_SJF() ...@@ -109,12 +123,14 @@ static void GiveMemory_SJF()
for( ;; ) for( ;; )
{ {
// Find the shortest process
for( proc = proc_min = new_proc; proc; proc = proc->next ) for( proc = proc_min = new_proc; proc; proc = proc->next )
{ {
if( proc->MEM_need < proc_min->MEM_need ) if( proc->MEM_need < proc_min->MEM_need )
proc_min = proc; proc_min = proc;
} }
// Assign memory or if no memory is available, break loop
if( proc_min && (index = mem_get(proc_min->MEM_need)) >= 0 ) if( proc_min && (index = mem_get(proc_min->MEM_need)) >= 0 )
{ {
proc_min->MEM_base = index; proc_min->MEM_base = index;
...@@ -125,6 +141,9 @@ static void GiveMemory_SJF() ...@@ -125,6 +141,9 @@ static void GiveMemory_SJF()
} }
} }
/*
* Shortest job first high-level scheduler with fairness threshold
*/
static void GiveMemory_SJF_fairness() static void GiveMemory_SJF_fairness()
{ {
int index, thres_max = 0; int index, thres_max = 0;
...@@ -135,6 +154,8 @@ static void GiveMemory_SJF_fairness() ...@@ -135,6 +154,8 @@ static void GiveMemory_SJF_fairness()
{ {
proc_long = NULL; proc_long = NULL;
// Find the shortest process and the process with the
// highest fairness threshold value
for( proc = proc_min = new_proc; proc; proc = proc->next ) for( proc = proc_min = new_proc; proc; proc = proc->next )
{ {
if( proc->MEM_need < proc_min->MEM_need ) if( proc->MEM_need < proc_min->MEM_need )
...@@ -147,14 +168,19 @@ static void GiveMemory_SJF_fairness() ...@@ -147,14 +168,19 @@ static void GiveMemory_SJF_fairness()
} }
} }
// Shortest process gives precedence to a process
// which exceeds the fairness threshold
if( proc_long && thres_max >= FAIRNESS_THRESHOLD ) if( proc_long && thres_max >= FAIRNESS_THRESHOLD )
proc = proc_long; proc = proc_long;
else else
proc = proc_min; proc = proc_min;
// The queue is empty
if( !proc ) if( !proc )
break; break;
// If memory is available, assign it to the process.
// Otherwise, increment its fairness value
if( (index = mem_get(proc->MEM_need)) >= 0 ) if( (index = mem_get(proc->MEM_need)) >= 0 )
{ {
proc->MEM_base = index; proc->MEM_base = index;
...@@ -194,7 +220,7 @@ static void ReclaimMemory() ...@@ -194,7 +220,7 @@ static void ReclaimMemory()
mem_free(proc->MEM_base); mem_free(proc->MEM_base);
proc->MEM_base = -1; proc->MEM_base = -1;
// Call the hl_handlertion that cleans up the simulated process // Call the function that cleans up the simulated process
rm_process(&proc); rm_process(&proc);
// See if there are more processes to be removed // See if there are more processes to be removed
...@@ -208,6 +234,7 @@ static void ReclaimMemory() ...@@ -208,6 +234,7 @@ static void ReclaimMemory()
static void my_finale() static void my_finale()
{ {
// Your very own code goes here // Your very own code goes here
// Less is more :-)
} }
/* /*
...@@ -221,9 +248,9 @@ void schedule(event_type event) ...@@ -221,9 +248,9 @@ void schedule(event_type event)
if( first ) if( first )
{ {
mem_init(memory); mem_init(memory);
finale = my_finale; finale = my_finale;
first = 0; first = 0;
int scheduler_type = 0; int scheduler_type = 0;
...@@ -231,7 +258,7 @@ void schedule(event_type event) ...@@ -231,7 +258,7 @@ void schedule(event_type event)
" 1. FCFS\n" " 1. FCFS\n"
" 2. SJF\n" " 2. SJF\n"
" 3. FCFFS\n" " 3. FCFFS\n"
" 4. FCFFS (met fairness)\n" " 4. SJF (met fairness)\n"
"Keuze: " "Keuze: "
); );
...@@ -245,19 +272,20 @@ void schedule(event_type event) ...@@ -245,19 +272,20 @@ void schedule(event_type event)
case 3: hl_handler = &GiveMemory_FCFFS; break; case 3: hl_handler = &GiveMemory_FCFFS; break;
case 4: hl_handler = &GiveMemory_SJF_fairness; break; case 4: hl_handler = &GiveMemory_SJF_fairness; break;
default: default:
fprintf(stderr, "Ongeldige invoer (alleen 1, 2, 3 of 4 toegestaan).\n"); fprintf(stderr,
"Ongeldige invoer (alleen 1 t/m 4 toegestaan).\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
break; break;
} }
printf("\n"); printf("\n");
int cpu_type = 0; int cpu_type = 0;
printf("Kies een cpu scheduler:\n" printf("Kies een cpu scheduler:\n"
" 0. FCFS (standaard)\n" " 0. FCFS (standaard)\n"
" 1. Round robin\n" " 1. Round robin\n"
" 2. SJF\n" " 2. LJF\n"
"Keuze: " "Keuze: "
); );
...@@ -268,9 +296,10 @@ void schedule(event_type event) ...@@ -268,9 +296,10 @@ void schedule(event_type event)
{ {
case 0: cpu_handler = &CPU_scheduler_FCFS; break; case 0: cpu_handler = &CPU_scheduler_FCFS; break;
case 1: cpu_handler = &CPU_scheduler_RR; break; case 1: cpu_handler = &CPU_scheduler_RR; break;
case 2: cpu_handler = &CPU_scheduler_SJF; break; case 2: cpu_handler = &CPU_scheduler_LJF; break;
default: default:
fprintf(stderr, "Ongeldige invoer (alleen 0, 1 of 2 toegestaan).\n"); fprintf(stderr,
"Ongeldige invoer (alleen 0 t/m 2 toegestaan).\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
break; break;
} }
...@@ -309,6 +338,9 @@ void schedule(event_type event) ...@@ -309,6 +338,9 @@ void schedule(event_type event)
} }
} }
/*
* Enqueue event at the front of the queue
*/
void enqueue_front(pcb **queue, pcb *elem) void enqueue_front(pcb **queue, pcb *elem)
{ {
// Attach the (non-empty) queue to the new item // Attach the (non-empty) queue to the new item
...@@ -322,8 +354,9 @@ void enqueue_front(pcb **queue, pcb *elem) ...@@ -322,8 +354,9 @@ void enqueue_front(pcb **queue, pcb *elem)
*queue = elem; *queue = elem;
} }
/* Enqueue an event at the back of a queue */ /*
* Enqueue an event at the back of a queue
*/
void enqueue_back(pcb **queue, pcb *elem) void enqueue_back(pcb **queue, pcb *elem)
{ {
pcb *last; pcb *last;
......
...@@ -7,6 +7,11 @@ ...@@ -7,6 +7,11 @@
Kruislaan 403 Kruislaan 403
Datum: 7 september 2003 Datum: 7 september 2003
Versie: 0.3 Versie: 0.3
Student name .... Sander van Veen & Taddeus Kroes
Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
Collegekaart .... 6167969 & 6054129
Date ............ 10.10.2010
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
......
PROGNAME = testqueue
CC = gcc
CFILES = queue.c
CFLAGS = -ansi -Wall -o2 -pedantic -g
LIBS = -lm
RM = rm -f
$(PROGNAME): $(CFILES)
$(CC) $(CFLAGS) $(CFILES) -o $@ $(LIBS)
clean:
$(RM) $(PROGNAME)
/*
* Test the enqueue/dequeue funtions for the process scheduler.
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct PCB
{
struct PCB *prev, *next;
int num;
} pcb;
void printQueue(pcb *queue);
pcb *createPCB(int i);
void enqueueFront(pcb **queue, pcb *elem);
void enqueueBack(pcb **queue, pcb *elem);
pcb *removeFromQueue(pcb **queue, pcb *elem);
pcb *dequeue(pcb **queue);/* Enqueue an event at the front of a queue */
int main(void)
{
pcb *queue = NULL;
printQueue(queue);
enqueueFront(&queue, createPCB(1));
printQueue(queue);
enqueueFront(&queue, createPCB(2));
printQueue(queue);
enqueueFront(&queue, createPCB(3));
printQueue(queue);
enqueueBack(&queue, dequeue(&queue));
printQueue(queue);
removeFromQueue(&queue, queue->next);
printQueue(queue);
return 0;
}
void printQueue(pcb *queue)
{
pcb *p;
printf("(");
for( p = queue; p; p = p->next )
printf("%d%s", p->num, p->next ? "," : "");
puts(")");
}
pcb *createPCB(int i)
{
pcb *p = malloc(sizeof(pcb));
p->next = p->prev = NULL;
p->num = i;
return p;
}
void enqueueFront(pcb **queue, pcb *elem)
{
/* Attach the (non-empty) queue to the new item */
if( *queue )
{
elem->next = *queue;
(*queue)->prev = elem;
}
/* Put the new element at the front of the queue */
*queue = elem;
}
/* Enqueue an event at the back of a queue */
void enqueueBack(pcb **queue, pcb *elem)
{
pcb *last;
/* Check if the queue is empty */
if( !(*queue) )
{
*queue = elem;
return;
}
/* Walk through the queue until the last queued item is reached */
for( last = *queue; last->next; last = last->next );
/* Attach the element to the last item */
last->next = elem;
elem->prev = last;
}
/* Remove and return an event from any position in a queue */
pcb *removeFromQueue(pcb **queue, pcb *elem)
{
/* Remove from front of queue. */
if( *queue == elem )
*queue = elem->next;
if( elem->next )
elem->next->prev = elem->prev;
if( elem->prev )
elem->prev->next = elem->next;
elem->next = elem->prev = NULL;
return elem;
}
/* Dequeue and return an event */
pcb *dequeue(pcb **queue)
{
return removeFromQueue(queue, *queue);
}
...@@ -38,8 +38,8 @@ computer. However, even in the current computer based age, most of the exams ...@@ -38,8 +38,8 @@ computer. However, even in the current computer based age, most of the exams
are still administered on paper or orally. This raises the first question: What are still administered on paper or orally. This raises the first question: What
is the reason of the lack of computer based exams? is the reason of the lack of computer based exams?
According to foo\footnote{bar}, there is. According to foo\footnote{bar}, there is.
%can all topics administered on a computer? % can all topics administered on a computer?
\section{The problem} \section{The problem}
\begin{itemize} \begin{itemize}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment