网站建设公司市场,wordpress正在建设中,宁波seo搜索引擎优化公司,济南网站制作哪家专业在 初探 C# GPU 通用计算技术 中#xff0c;我使用 Accelerator 编写了一个简单的 GPU 计算程序。也简单看了一些 Brahma 的代码#xff0c;从它的 SVN 最新代码看#xff0c;Brahma 要转移到使用 OpenCL.Net 作为底层了#xff0c;于是也去网上搜索了一下#xff0c;发现… 在 初探 C# GPU 通用计算技术 中我使用 Accelerator 编写了一个简单的 GPU 计算程序。也简单看了一些 Brahma 的代码从它的 SVN 最新代码看Brahma 要转移到使用 OpenCL.Net 作为底层了于是也去网上搜索了一下发现了 OpenCL.Net 和另一个相关的项目 OpenCLTemplate。 看了一些它的代码颇像 DirectCompute 的风格其 GPU 程序是标准 C 代码所以编写和阅读也容易一些而 Host 程序是 C# 的把 GPU 代码字符串传给编译器进行编译然后就可以在 C# 对它进行调用并且取回结果了。 安装了 ati-stream-sdk-v2.1-vista-win7-64折腾了一下它的例子程序 FirstOpenCLProgram运行时会抛出一个 InvalidContext 的异常到它的论坛去问版主建议我安装 ati 最新 driver 先虽然觉得本本刚买没几天应该驱动比较新还是去安装了最新的驱动果然不再报异常了。只是如果直接引用 OpenCLTemplate 下的 OpenCL.NET.dll 和 OpenCLTemplate.dll 的话在初始化的时候会报空指针而引用 FirstOpenCLProgram 下的这两个 dll 的话则初始化时会闪现好几个控制台窗口但是后续都是正常的。 既然正常了就还是以上次那个程序来看看 OpenCL 的方式会不会有更大的速度提升。 使用 OpenCL 的程序代码如下 代码 private const int GridSize 1024;
private readonly float[] _map;private const string Code
__kernel void Test(__global float* v1)
{int i get_global_id(0);float p v1[i];v1[i] p * p * p / 4 194;
};
private readonly CLCalc.Program.Kernel _test;
private readonly CLCalc.Program.Variable _vmap;
private readonly CLCalc.Program.Variable[] _args;
private readonly int[] _workers;public Form1()
{InitializeComponent();_map new float[GridSize * GridSize];for (int y 0; y GridSize; y){for (int x 0; x GridSize; x){_map[x * GridSize y] x * y;}}CLCalc.InitCL();CLCalc.Program.Compile(new[] { Code });_test new CLCalc.Program.Kernel(Test);_vmap new CLCalc.Program.Variable(_map);_args new[] { _vmap };_workers new[] { GridSize * GridSize };Render();
}private void Start_Click(object sender, EventArgs e)
{var stopwatch new Stopwatch();stopwatch.Start();_test.Execute(_args, _workers);_vmap.ReadFromDeviceTo(_map);var time stopwatch.ElapsedMilliseconds;this.Text time.ToString();Render();
}private void Render()
{var workingBitmap new Bitmap(pictureBox1.Width, pictureBox1.Height);for (int y 0; y pictureBox1.Height; y){for (int x 0; x pictureBox1.Width; x){workingBitmap.SetPixel(x, y, Color.FromArgb(-0x1000000 | (int)_map[x * 2 * GridSize y * 2]));}}pictureBox1.Image workingBitmap;
} 运行程序点击 4 次按钮显示图形和前两个程序相同说明程序运算正常4 次时间为8、8、7、8。比使用 Accelerator 的程序速度也快了 5 倍以上。 因为是标准 C 程序所以我们的自由度很大我也在 OpenCL 下实现了一下 Life 游戏C# 部分的代码就不贴了GPU 代码如下 代码 #define width 512
#define length 262144int GetValue(__global int* v, int index)
{if(index 0 || index length){return 0;}return v[index] 0 ? 0 : 1;
};__kernel void Test(__global int* v)
{int i get_global_id(0);int topLeft GetValue(v, i - width - 1);int top GetValue(v, i - width);int topRight GetValue(v, i - width 1);int left GetValue(v, i - 1);int current GetValue(v, i);int right GetValue(v, i 1);int bottomLeft GetValue(v, i width - 1);int bottom GetValue(v, i width);int bottomRight GetValue(v, i width 1);int liveNeighbors topLeft top topRight left right bottomLeft bottom bottomRight;if(current 0){v[i] ((liveNeighbors 2) || (liveNeighbors 3)) ? 0 : 255;}else{v[i] (liveNeighbors 3) ? 255 : 0;}
}; 很长时间不用 C有很多像函数声明顺序等规则都忘了好的一点是 OpenCL.Net 中还提供了 OpenCLCodeChecker用来进行代码检测同时也在侧边栏里提供了语言帮助只是它的检测稍嫌弱智代码稍微复杂提示的错误位置很奇怪有时候告知编译出错Log 里面却没有任何错误信息。不过总体来说帮助还是很大就是了。 这个 Life 程序有一个小 Bug在于没有判断超出右边界的代码所以如果左边有生物右边虽然原来没有生物也会无中生有 :) 总的来说用 OpenCL.Net 编程感觉还是很愉快的。