核心是GHC的中间语言.阅读核心可以帮助您更好地了解您的计划的性能.有人问我关于阅读Core的文档或教程,但我找不到多少.
有哪些文档可供阅读GHC Core?
这是我到目前为止所发现的:
在解决一些项目Euler问题以学习Haskell(所以目前我是一个完全初学者)时,我遇到了问题12.我写了这个(天真的)解决方案:
--Get Number of Divisors of n
numDivs :: Integer -> Integer
numDivs n = toInteger $ length [ x | x<-[2.. ((n `quot` 2)+1)], n `rem` x == 0] + 2
--Generate a List of Triangular Values
triaList :: [Integer]
triaList = [foldr (+) 0 [1..n] | n <- [1..]]
--The same recursive
triaList2 = go 0 1
where go cs n = (cs+n):go (cs+n) (n+1)
--Finds the first triangular Value with more than n Divisors
sol …
Run Code Online (Sandbox Code Playgroud) 在Haskell中进行编程时(特别是在解决Project Euler问题时,其中次优解决方案往往会对CPU或内存需求造成压力)我经常感到困惑,为什么程序的行为方式如此.我看一下配置文件,尝试引入一些严格,选择另一种数据结构,...但主要是它在黑暗中摸索,因为我缺乏良好的直觉.
此外,虽然我知道如何实现Lisp,Prolog和命令式语言,但我不知道实现一种懒惰的语言.我也有点好奇.
因此,我想了解更多关于从程序源到执行模型的整个链.
我想知道的事情:
应用了哪些典型的优化?
当有多个评估候选者时,执行顺序是什么(虽然我知道它是从所需的输出驱动的,但是在首先评估A然后B之后可能仍然存在很大的性能差异,或者首先评估B以检测到您不需要一点都不)
thunk如何代表?
如何使用堆栈和堆?
什么是CAF?(分析表明有时热点在那里,但我没有线索)
我正在为类似MineCraft的世界开发地形生成算法.目前,我正在使用基于"Simplex Noise Demystified"[PDF]文章中的实现的单纯形噪声,因为单纯形噪声应该比Perlin噪声更快并且具有更少的伪像.这看起来相当不错(见图),但到目前为止它也很慢.
运行噪声功能10次(我需要不同波长的噪声,如地形高度,温度,树位置等),每个块中的块(16x16x128块)有3个八度的噪声,或大约100万次调用噪声功能总共需要700-800毫秒.尽管算法中没有明显昂贵的操作(至少对我而言),但这对于以任何体面的速度生成地形的目的而言至少是一个数量级太慢.只是楼层,模数,一些数组查找和基本算术.下面列出了算法(用Haskell编写).SCC评论用于分析.我省略了2D噪声函数,因为它们的工作方式相同.
g3 :: (Floating a, RealFrac a) => a
g3 = 1/6
{-# INLINE int #-}
int :: (Integral a, Num b) => a -> b
int = fromIntegral
grad3 :: (Floating a, RealFrac a) => V.Vector (a,a,a)
grad3 = V.fromList $ [(1,1,0),(-1, 1,0),(1,-1, 0),(-1,-1, 0),
(1,0,1),(-1, 0,1),(1, 0,-1),(-1, 0,-1),
(0,1,1),( 0,-1,1),(0, 1,-1),( 0,-1,-1)]
{-# INLINE dot3 #-}
dot3 :: Num a => (a, a, a) -> a -> a -> a -> …
Run Code Online (Sandbox Code Playgroud) floating-point polymorphism performance haskell procedural-generation
未装箱的类型,比如Int#
,和严格的功能,f (!x) = ...
是不同的,但我看到概念上的相似性 - 他们在某种程度上不允许暴力/懒惰.如果Haskell是像Ocaml这样的严格语言,那么每个函数都是严格的,并且每个类型都是未装箱的.unboxed类型与强制执行之间的关系是什么?
我正在Haskell中编写一个游戏,而我在UI上的当前传递涉及很多程序生成的几何体.我目前专注于识别一个特定操作(C-ish伪代码)的性能:
Vec4f multiplier, addend;
Vec4f vecList[];
for (int i = 0; i < count; i++)
vecList[i] = vecList[i] * multiplier + addend;
Run Code Online (Sandbox Code Playgroud)
也就是说,沼泽标准的四个浮点数的乘法加法,这是SIMD优化成熟的事情.
结果将转到OpenGL顶点缓冲区,因此最终必须将其转储到平面C数组中.出于同样的原因,计算可能应该在C'浮点'类型上完成.
我已经找到了一个库或本地惯用解决方案来在Haskell中快速完成这类工作,但我提出的每个解决方案似乎都徘徊在性能的2%左右(即,慢50倍) GCC带有正确的旗帜.当然,我几周前开始使用Haskell,所以我的经验有限 - 这就是为什么我要来找你们.您是否可以为更快的Haskell实现提供建议,或者指向如何编写高性能Haskell代码的文档?
首先,最新的Haskell解决方案(时钟约12秒).我尝试了这个SO帖子中的爆炸模式,但它并没有给AFAICT带来任何影响.将'multAdd'替换为'(\ iv - > v*4)'将执行时间缩短到1.9秒,因此按位(以及随后的自动优化挑战)似乎没有太多错误.
{-# LANGUAGE BangPatterns #-}
{-# OPTIONS_GHC -O2 -fvia-C -optc-O3 -fexcess-precision -optc-march=native #-}
import Data.Vector.Storable
import qualified Data.Vector.Storable as V
import Foreign.C.Types
import Data.Bits
repCount = 10000
arraySize = 20000
a = fromList $ [0.2::CFloat, 0.1, 0.6, 1.0]
m = fromList $ [0.99::CFloat, 0.7, 0.8, 0.6] …
Run Code Online (Sandbox Code Playgroud) 这是我对一种treap的实现(使用隐式键和一些存储在节点中的附加信息):http://hpaste.org/42839/treap_with_implicit_keys
根据分析数据,GC占用该程序80%的时间.据我所知,这是因为每次节点被"修改"时,都会重新创建到根节点的每个节点.
我能在这里做些什么来提高性能还是我必须进入ST monad的领域?
optimization performance garbage-collection haskell data-structures
haskell ×7
performance ×5
ghc ×2
optimization ×2
evaluation ×1
heap-memory ×1
math ×1
polymorphism ×1
profiling ×1
simd ×1
strictness ×1