使用诸如Parallel Linq之类的系统,可以在单个机器中的多个核心和线程之间分离匿名函数,查询等的执行。我希望能够使用标准语言结构(例如for {Parallel.For()
),值类型(如int
s,struct
等)将其扩展为跨多台计算机运行。 ,并将应用程序源修改保持在最低限度。理想情况下,这将允许我打开一个项目,向方法添加属性,并重新编译以获得对增强功能的访问。
似乎我需要的是:
捕获已编译的代码块(例如lambda)并将其传递给在另一个节点上运行的工作进程以及所需的任何数据的能力,或者
提供一个预处理程序,它将捕获有问题的代码,在一个模板项目中编译它,它将替换变量引用等,引用一个类来处理网络通信,缓存和访问任何其他必需的资产,并将生成的DLL发送到在其他计算机上运行的任何可用的工作节点。
Roslyn似乎提供了一些在这里很有用的工具。有没有办法挂钩到当前的编译管道允许这个?
修改
好的,我知道这是可能的,because these guys did it。问题是,如何?
答案 0 :(得分:11)
使用Parallel Linq等系统,可以跨单个机器内的多个核心和线程分离匿名函数,查询等的执行。我希望能够使用标准语言结构(例如for循环(如Parallel.For()),值类型(如整数,结构等)来扩展它以跨多台机器运行,并将应用程序源修改保持在最低限度
听起来不错。事实上,我们在Microsoft Research中有一个非常类似的系统,但显然我无法讨论细节。
我需要能够捕获已编译的代码块(例如lambda)并将其传递给在另一个节点上运行的工作进程以及所需的任何数据
好的,你已经明白了。我们将该功能添加到C#3中。这就是LINQ to SQL的工作原理。 以某种方式 LINQ查询必须进入数据库。编译的lambda在客户端计算机上被查询,转换为一个发送到服务器节点的查询,然后将结果发回。
Roslyn似乎提供了一些在这里很有用的工具。有没有办法挂钩到当前的编译管道允许这个?
这不是罗斯林的目的; Roslyn不是要为C#语言添加新功能。这是为了更容易分析代码来构建重构引擎等。
您无需挂钩编译管道。 PLINQ不会更改编译器,LINQ to SQL不会更改编译器,依此类推。将lambda转换为表达式树时,编译器会发出代码,该代码在运行时创建表示树的表达式树。您可以查询该表达式树,将其序列化到网络中的另一台计算机,对其进行反序列化,将其转换为委托并运行它,如果这是您喜欢的事情。
您可能需要编写自己的表达式树序列化器和反序列化器,但它们是非常简单的数据结构。作为一个不可变树应该使它们很容易序列化和反序列化;它们不能真正形成复杂的网络,因为它们总是由叶子节点构成。
答案 1 :(得分:10)
你不必将语言延伸到Brahma做的事情。他刚刚实现了一个自定义查询提供程序,它解析表达式树并发出GPGPU代码(LINQ to SQL做同样的事情,但使用SQL)。
我在MSDN上发布了一个基本指南here,可以帮助您实现IQueryable
提供商。
困难的部分将遍历表达式树并生成OpenCL代码。一旦你能做到这一点,你就把它传递给Cloo,你就应该跑步了。
修改强>
您将编译标准.NET代码的工具与具有属性[Kernel]
的GPU代码相关联。他们通过使用后构建工具查找已编译IL中的属性来执行此操作,并执行IL重写以生成GPU调用。这类似于PostSharp,一种AOP解决方案。
IL重写是耗时且艰苦的工作,但你也可以走这条路。