summaryrefslogtreecommitdiff
path: root/ws2015
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2015-12-05 22:35:04 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2015-12-05 22:35:04 +0100
commit3ed0cb4697ea917830b9913cfe70ae1c3ec6820e (patch)
tree68200a979ae485f8abe3783b1300b79cc487d0b3 /ws2015
parente41963dcfea8fba746a99d76d4933e9e231dbcd8 (diff)
downloaduni-3ed0cb4697ea917830b9913cfe70ae1c3ec6820e.tar
uni-3ed0cb4697ea917830b9913cfe70ae1c3ec6820e.tar.gz
uni-3ed0cb4697ea917830b9913cfe70ae1c3ec6820e.tar.bz2
uni-3ed0cb4697ea917830b9913cfe70ae1c3ec6820e.tar.xz
uni-3ed0cb4697ea917830b9913cfe70ae1c3ec6820e.zip
Setup for FFP 08
Diffstat (limited to 'ws2015')
-rw-r--r--ws2015/ffp/blaetter/08/FFP_U08_Parallel.hs219
1 files changed, 219 insertions, 0 deletions
diff --git a/ws2015/ffp/blaetter/08/FFP_U08_Parallel.hs b/ws2015/ffp/blaetter/08/FFP_U08_Parallel.hs
new file mode 100644
index 0000000..8615dad
--- /dev/null
+++ b/ws2015/ffp/blaetter/08/FFP_U08_Parallel.hs
@@ -0,0 +1,219 @@
1-- Fortgeschrittene Funktionale Programmierung,
2-- LMU, TCS, Wintersemester 2015/16
3-- Steffen Jost, Alexander Isenko
4--
5-- Übungsblatt 07. 9.12.2015
6--
7-- Thema: Paralleles Rechnen
8--
9-- Hinweis:
10-- Falls Ihr Rechner nur 1--2 echte Prozessorkerne besitzt,
11-- dann loggen Sie sich für diese Übungen in einem Rechner am
12-- CIP-Pool der Informatik ein.
13-- Informationen zum Remote-Login am CIP-Pool finden Sie auf:
14-- http://www.rz.ifi.lmu.de/FAQ/index.html
15-- Abschnitt "Von zu Hause/remote aus ..."
16-- Prüfen Sie auch, dass der gewählte Rechner über freie Kapazitäten verfügt,
17-- z.B. mit dem Tool "htop". Falls der Rechner beschäftigt ist,
18-- dann loggen Sie sich von dem Remote-Rechner weiter zu einem
19-- der anderen intern erreichbaren CIP-Arbeitsplatzrechner ein, siehe:
20-- http://www.rz.ifi.lmu.de/FAQ/Rechnerliste.faq.html
21--
22-- Es ist für diese Übung zwingend notwendig, einen Rechner
23-- mit mehreren Prozessorkernen einzusetzen. Schließlich dreht es
24-- sich darum, eine Berechnung durch die gleichzeitge Verwendung
25-- mehrerer Kerne zu beschleunigen.
26--
27-- Für die nächste Übung 8 zum Thema Nebenläufigkeit reicht
28-- dann auch wieder ein einzelner Prozessorkern.
29--
30--
31-- Anweisungen:
32-- Es empfiehlt sich heute, die Übungen in einer zur Vorlesung
33-- umgekehrten Reihenfolge zu bearbeiten, da die Par-Monade
34-- vermutlich das am einfachsten einzusetzende Konzept ist.
35-- Für die Vorlesung wurde eine andere Reihenfolge gewählt,
36-- um die einzelnen Konzepte besser zu motivieren.
37--
38-- Gehen Sie diese Datei durch und bearbeiten Sie
39-- alle Vorkommen von undefined bzw. die mit -- !!! TODO !!!
40-- markierten Stellen. Testen Sie Ihre Lösungen mit GHC!
41--
42-- Die Verwendung mehrerer Kerne läßt sich mit dem Interpreter
43-- (ghci) nur schlecht messen. Kompilieren Sie Ihre Lösung daher
44-- mit ghc, ggf. jede Aufgabe in eine eigene Datei auslagern:
45-- > ghc MyProgA71.hs -O2 -threaded -rtsopts
46--
47-- und dann mit gewünschter Anzahl echter Threads ausführen:
48-- > time ./MyProgA71 +RTS -N4 -s
49-- > time ./MyProgA71 +RTS -N3 -s
50-- > time ./MyProgA71 +RTS -N2 -s
51-- > time ./MyProgA71 +RTS -N1 -s
52-- die Angabe unter "Total -> elapsed" ist dann ein brauchbares Maß.
53--
54
55-- _________________________________________________
56-- | |
57-- | * Par-Monade kennenlernen |
58-- | * Parallel Strategies kennenlernen |
59-- | * seq / deepseq kennenlernen |
60-- |_________________________________________________|
61-- λ/
62-- /|
63-- / \
64
65import Data.List
66import Control.Monad
67import Control.Monad.Par -- ggf. cabal oder "stack install monad-par" ausführen
68import Control.Parallel
69import Control.Parallel.Strategies
70import Control.DeepSeq
71
72import System.Environment (getArgs)
73
74-- !!! TODO !!! Je nach bearbeiteter Aufgabe auskommentieren:
75main = main' [ ("1", main_A7_1)
76 , ("2", main_A7_2)
77 , ("3", main_A7_3)
78 ]
79
80main' calls = do
81 args <- getArgs
82 mapM_ (\(s, x) -> when (s `elem` args) x) calls
83
84-- A7-1 Par-Monade
85--
86-- Beschleunigen Sie die Ausführung des folgenden Programmes
87-- durch den Einsatz einer Par-Monade zur Berechnung.
88--
89-- Hinweis: Sie sollen nur innerhalb der main-Funktion arbeiten.
90-- Die Funktion hanoi dient nur als Last, also diese selbst nicht beschleunigen.
91
92main_A7_1 :: IO ()
93main_A7_1 = main' [ ("seq", main_A7_1seq)
94 , ("par", main_A7_1par)
95 ]
96
97main_A7_1seq :: IO ()
98main_A7_1seq = do
99 let difficulty = 25 -- ändern, falls Laufzeit zu lang oder zu kurz ist
100 t1 = length $ hanoi difficulty 1 2
101 t2 = length $ hanoi difficulty 1 3
102 t3 = length $ hanoi difficulty 2 3
103 t4 = length $ hanoi difficulty 3 1
104 t1 `par` t2 `par` t3 `par` t4 `pseq` putStrLn "Wusstest Du schon:"
105 putStrLn $ "Man braucht " ++ (show t1) ++ " Schritte um einen Hanoi-Turm der Größe "
106 ++ (show difficulty) ++ " von Platz 1 auf Platz 2 zu versetzen."
107 putStrLn $ "Man braucht " ++ (show t2) ++ " Schritte um einen Hanoi-Turm der Größe "
108 ++ (show difficulty) ++ " von Platz 1 auf Platz 3 zu versetzen."
109 putStrLn $ "Man braucht " ++ (show t3) ++ " Schritte um einen Hanoi-Turm der Größe "
110 ++ (show difficulty) ++ " von Platz 2 auf Platz 3 zu versetzen."
111 putStrLn $ "Man braucht " ++ (show t4) ++ " Schritte um einen Hanoi-Turm der Größe "
112 ++ (show difficulty) ++ " von Platz 3 auf Platz 1 zu versetzen."
113 putStrLn "Gut zu wissen, oder?"
114
115
116main_A7_1par :: IO () -- parallele Version
117main_A7_1par = undefined -- !!! TODO !!!
118
119
120-- Hilfsfunktionen, zur Erzeugung von Rechnenlast, bitte nicht verändern:
121hanoi :: Int -> Int -> Int -> [(Int,Int)]
122hanoi 1 i j = [(i,j)]
123hanoi n i j = hanoi n' i otherTower
124 ++ [(i,j)]
125 ++ hanoi n' otherTower j
126 where
127 n' = n-1
128 otherTower = 1+2+3-i-j
129
130
131
132-- A7-2 Parallel.Strategies
133--
134-- In der Vorlesung wurden parallele Strategien vorgestellt.
135-- Implementieren Sie ein parallel-beschleunigtes Quicksort unter Verwendung von
136-- Strategien aus Control.Parallel.Strategies!
137--
138-- Testen und vergleichen Sie verschiedene Auswerte-Strategien!
139-- Welche ist die Beste und warum?
140--
141-- Hinweis:
142-- Die Laufzeit mit einem Kern sollte im CIP-Pool ca. 1 Minuten dauern.
143
144quicksortS :: [Integer] -> [Integer]
145quicksortS [] = []
146quicksortS (x:xs) = result
147 where
148 result = losort ++ (x:hisort)
149 losort = quicksortS [y | y <- xs, y < x]
150 hisort = quicksortS [y | y <- xs, y >= x]
151
152quicksortP :: [Integer] -> [Integer]
153quicksortP xs = undefined -- !!! TODO !!!
154
155
156main_A7_2 = do
157 args <- getArgs
158 let qs
159 | "seq" `elem` args = quicksortS
160 | otherwise = quicksortP
161 putStrLn "Berechnung von Quicksort gestartet."
162 let list1 = [1,7..30000] ++ (reverse [1..45678]) ++ [2,4..30000]
163 let qlist1 = qs list1
164 let len1 = deepseq qlist1 (length list1)
165 let list2 = concat $ permutations $ [1..7]
166 let qlist2 = qs list2
167 let len2 = deepseq qlist2 (length list2)
168 putStrLn $ "Berechnung von Quicksort mit Liste der Länge " ++ (show len1) ++ ":"
169 -- putStrLn $ show $ take 33 $ drop 22222 $ quicksortS list1
170 putStrLn $ "Berechnung von Quicksort mit Liste der Länge " ++ (show len2) ++ ":"
171 -- putStrLn $ show $ take 33 $ drop 22222 $ quicksortS list2
172 putStrLn $ "Done."
173
174
175
176-- A7-3 par und pseq
177--
178-- Betrachten Sie die Funktionen pay und payL, welche für einen gegebenen Betrag
179-- und einer gegebenen Menge Münzen [(Münzgröße,Anzahl)] alle Möglichkeiten
180-- ausgibt, diesen Betrag mit den Münzen zu bezahlen:
181-- pay 10 [(3,3),(5,2),(1,2)] = [[(5,2)],[(1,2),(3,1),(5,1)],[(1,1),(3,3)]]
182--
183-- Beschleunigen Sie die Ausführung der Funktion pay bzw. payL
184-- durch den Einsatz von par und pseq
185--
186type Münzgröße = Integer
187type Anzahl = Integer
188type Betrag = Integer
189
190main_A7_3 = do
191 let value = 2345
192 let coins = [(23,25),(11,25),(33,50),(5,25),(3,25),(1,25)]
193 putStrLn $ "Berechne die Möglichkeiten den Wert " ++ (show value) ++ " mit den Münzen & Scheinen " ++ (show coins) ++ " darzustellen:"
194 let poss = pay value coins
195 -- mapM_ print $ poss
196 putStrLn $ "Es gibt " ++ (show $ length poss) ++ " Möglichkeiten den Wert " ++ (show value) ++ " mit den Münzen & Scheinen " ++ (show coins) ++ " darzustellen!"
197
198pay :: Betrag -> [(Münzgröße, Anzahl)] -> [[(Münzgröße, Anzahl)]]
199pay val coins = map count $ payL [] val (sortBy (\(a,_) (c,_) -> invert $ compare a c) coins)
200
201payL :: [Integer] -> Betrag -> [(Münzgröße,Anzahl)] -> [[Integer]]
202payL acc 0 coins = [acc]
203payL acc _ [] = []
204payL acc val ((c,qty):coins)
205 | c > val = payL acc val coins
206 | otherwise = left ++ right
207 where
208 left = payL (c:acc) (val - c) coins'
209 right = payL acc val coins
210 coins' | qty == 1 = coins
211 | otherwise = (c,qty-1) : coins
212
213count :: [Integer] -> [(Integer,Integer)]
214count xs = [(head ks, genericLength ks) | ks <- group $ sort xs]
215
216invert :: Ordering -> Ordering
217invert EQ = EQ
218invert LT = GT
219invert GT = LT