下面似乎有用...但它看起来很笨拙.
data Point = Point Int Int
data Box = Box Int Int
data Path = Path [Point]
data Text = Text
data Color = Color Int Int Int
data WinPaintContext = WinPaintContext Graphics.Win32.HDC
class CanvasClass vc paint where
drawLine :: vc -> paint -> Point -> Point -> IO ()
drawRect :: vc -> paint -> Box -> IO ()
drawPath :: vc -> paint -> Path -> IO ()
class (CanvasClass vc paint) => TextBasicClass vc paint where …Run Code Online (Sandbox Code Playgroud) 假设我正在尝试对数组大小n进行简单的缩减,比如保持在一个工作单元内...说添加所有元素.一般策略似乎是在每个GPU上生成许多工作项,这会减少树中的项目.天真地看起来似乎采取了log n步骤,但它并不像第一波线程所有这些线程一次性进行,是吗?它们被安排在经线中.
for(int offset = get_local_size(0) / 2;
offset > 0;
offset >>= 1) {
if (local_index < offset) {
float other = scratch[local_index + offset];
float mine = scratch[local_index];
scratch[local_index] = (mine < other) ? mine : other;
}
barrier(CLK_LOCAL_MEM_FENCE);
}
Run Code Online (Sandbox Code Playgroud)
因此,并行添加了32个项目,然后该线程在屏障处等待.另外32人去,我们在障碍物等待.另外32个,我们在屏障处等待,直到所有线程都完成了必要的n/2次添加以进入树的最顶层,然后我们绕过循环.凉.
这看起来不错,但也许很复杂?我理解指令级并行是一个大问题,所以为什么不产生一个线程并做类似的事情
while(i<array size){
scratch[0] += scratch[i+16]
scratch[1] += scratch[i+17]
scratch[2] += scratch[i+17]
...
i+=16
}
...
int accum = 0;
accum += scratch[0]
accum += scratch[1]
accum += scratch[2]
accum += scratch[3]
...
Run Code Online (Sandbox Code Playgroud)
这样所有的添加都发生在经线内.现在你有一个线程可以保持gpu的忙碌程度.
现在假设指令级并行性不是真的.如下所示,工作大小设置为32(warp数).
for(int i …Run Code Online (Sandbox Code Playgroud) 假设我有一组记录,如
data A = A { a:: String } deriving (Show)
data B = B { b:: String } deriving (Show)
Run Code Online (Sandbox Code Playgroud)
然后是一些类型的类
class Foo a where
foo :: a -> IO ()
instance Foo A where
foo c = ...
Run Code Online (Sandbox Code Playgroud)
我也想做点什么
bar = do
push (A {a="x"})
push (B {b="y"})
Run Code Online (Sandbox Code Playgroud)
并且让这些东西最终放在某个地方,以便稍后运行,这样我就可以
map foo l
Run Code Online (Sandbox Code Playgroud)
我应该编写模板haskell来生成包装器类型并派生实例,以便列表可以是包装器类型吗?有更聪明的方法来解决这个问题吗?我老实说感觉受到haskell类型系统的影响,并且知道必须有更好的方法来做到这一点.