2011-01-13 13 views
5

私はいくつかのコードを最適化する方法を理解しようとしています。ここでは、次のとおりです。インライン関数が引き続き.profファイルに表示される


{-# OPTIONS_GHC -funbox-strict-fields #-} 

data Vec3 a = Vec3 !a !a !a 

vx :: Vec3 a -> a 
vx (Vec3 x _ _) = x 
{-# SPECIALIZE INLINE vx :: Vec3 Double -> Double #-} 

vy :: Vec3 a -> a 
vy (Vec3 _ y _) = y 
{-# SPECIALIZE INLINE vy :: Vec3 Double -> Double #-} 

vz :: Vec3 a -> a 
vz (Vec3 _ _ z) = z 
{-# SPECIALIZE INLINE vz :: Vec3 Double -> Double #-} 


dot :: (Num a) => Vec3 a -> Vec3 a -> a 
dot u v = (vx u * vx v) + (vy u * vy v) + (vz u * vz v) 
{-# SPECIALIZE INLINE dot :: Vec3 Double -> Vec3 Double -> Double #-} 


type Vec3D = Vec3 Double 

-- just make a bunch of vecs to measure performance 

n = 1000000 :: Double 

v1s = [Vec3 x y z | (x, y, z) <- zip3 [1 .. n] [2 .. n + 1] [3 .. n + 2]] 
     :: [Vec3D] 

v2s = [Vec3 x y z | (x, y, z) <- zip3 [3 .. n + 2] [2 .. n + 1] [1 .. n]] 
     :: [Vec3D] 


dots = zipWith dot v1s v2s :: [Double]  
theMax = maximum dots :: Double 
main :: IO() 
main = putStrLn $ "theMax: " ++ show theMax 

私はGHC 6.12.1でコンパイルすると(Ubuntuのi486のマシン上のLinux)

GHC --make -O2 Vec.hs -prof -auto -all -fforce-recomp

と実行

Vecを+ RTS -p

は、私は、関数VXおよびVYは、時間の大部分を取ることがわかり


COST CENTRE     MODULE    %time %alloc 

v2s       Main     30.9 36.5 
v1s       Main     27.9 31.3 
dots       Main     27.2 27.0 
CAF       GHC.Float    4.4 5.2 
vy        Main     3.7 0.0 
vx        Main     2.9 0.0 
theMax       Main     2.2 0.0 

、Vec.profファイルを見てみます。

なぜですか?私は、SPECIALIZE INLINEプラグマがこれらの機能がなくなる と考えました。非多型

data Vec3D = Vec3D {vx, vy, vz :: !Double} deriving Show 

を使用する場合

機能VX、VY、VZはコストセンターとして表示されません。

+1

実際にコアを見ましたか? '-ddump-core'でコンパイルし、何が起こったのか見てみましょう。 – fuz

答えて

2

これは、-auto-allを使用することの副作用であると思われます。これは、GHCが通常実行する多くの最適化(インライン展開を含む)を禁止します。私はあなたの非多型バージョンの違いは、実際にvxvy、およびvzが、多形性のためではなくレコード構文で定義されていると思われます(しかし、これについて間違っている可能性があります)。

-auto-allを使用する代わりに、モジュールにエクスポートリストを追加し、 "-auto"でコンパイルするか、SCCプラグマを使用してコストセンターを手動で設定してください。とにかく私はしばしばlet-bound関数にそれらを設定したいので、私は通常SCCプラグマを使います。-leto-allはそうしません。

2

回答にコメントを付ける方法がわからないので、私はこの回答にコメントをしています。

まず、お返事いただきありがとうございます。

FUZxxl:-ddump-coreを試して、-ddump-coreが認識できないというエラーメッセージが表示されました。多分あなたは、実世界のハスケルが推奨している本であるが、私はその出力をどのように読むのか分からないと思っています。私は "vx"などの出力ファイルを調べましたが、それらを見たことはありませんでした。私はコアを読む方法を学ぶべきだと思います。そのための良いガイドがありますか?

ジョン:私はそれを正しく読んでいる場合はGHCのflag reference documentationによると、-autoと-auto-すべての両方、機能ないマークされたINLINEに_scc_sを追加想定しています。 -autoがうまく動作するかどうかを確認するために、別のファイル/モジュールにVec3(Vec3)、vx、vy、vz、およびドットをエクスポートした別のテストケースを作成しました。このモジュールをMain.hsファイルにインポートしました。これらを-autoでコンパイルすると、私はまだ.profファイルにvx、vy、vzが見えました。

日時:違いが原因レコード構文の代わりに、多型にすることができることをあなたのコメント、私はまだ

data Vec3 a = Vec3 {vx, vy, vz :: !a} 

VX、VYとVZを定義したときので差は、原因遺伝子多型の可能性が高いと信じています.profファイルに現れました。

adad

+0

質問には実際のアカウントを使用することを検討する必要があります。あなたがそのような記述を持っているなら、あなたの評判が十分に高いときには、最初にあなた自身の質問に、次に何かに分けておくことができます。 – fuz

+0

アドバイスいただきありがとうございます。私は今それをやった。 – Tad

関連する問題