第12章 WebCL:使用OpenCL加速Web应用 - 12.7 服务器端使用WebCL
WebCL为计算而生,其可以使用在浏览器中,也可以使用与单独的JavaScript应用和服务中。Node.js是一款基于Chrome编译出的JavaScript运行时,其有运行速度快和网络应用可扩展能力强的特性。Node.js使用事件驱动,无阻塞输入/输出模型,让其集高性能和轻量化于一身。其实现的数据敏感、实时性的应用,在分布设备上的表现十分出色[1]。Node.js具有很好的模块化,其已经有超过80000个模块存在,其中一个就是node-webcl[2]。node-webcl也具有扩展特性,使用了一些Node.js标准中的特性(例如,使用Node.js内存时,和数组的方式一致),其他特性在未来可能会考虑放在WebCL的标准中发布。
安装node-webcl要比安装浏览器麻烦许多。其作为开发工具,需要依赖一些第三方库,并且需要重新编译。
- 首先,确认OpenCL的SDK能够使用你的CPU和GPU:
- 从这里安装Node.js
- 安装node-gyp:npm install -g node-gyp
- 安装node-image:
- 在这里下载FreeImage库和头文件
- npm install node-image
如果你想使用WebGL的互操作扩展开发应用,你还需要安装node-webgl和node-glfw:
建议将上面GLEW,AntTwekBar,FreeImage和GLFW包中的库文件和头文件,放置在你的头文件和库文件目录下面,这样在编译各个Node.js模块时,便于编译器进行查找;否则,你就需要修改binding.gyp文件。以上四个库在所有桌面平台(Mac,Windows和Linux)是可用的,并且在Linux和Mac下可以使用安装包管理器进行安装,比如apt-get和Homebrew[3]。
为了在代码中使用node-webcl,先打开编辑器,你需要将WebCL的API添加入全局命名空间中。下面webcl对象,就和浏览器中的window.webcl对象一样。
// add WebCL API
var webcl = require('node-webcl');
// rest of the code is identical to that in browser
将代码中的”require(‘node-webcl’)”换成webcl=window.webcl就能让这段代码在支持WebCL的浏览器中生效。通过node-webcl,我们就能使用操作系统中的访问方式,并且能使用所有Node.js中的模块。
在Node.js中使用node-webcl,无论是对服务器上的计算进行加速,还是对浏览器的Web接口的交互进行加速[4],对于网络访问都是十分有意义的事情[5]。
同样,不同的应用使用的编程框架也不同,比如:Python, R和MATLAB等。脚本语言提供一些特性,也可以用于JavaScript。虽然框架不同,但是很多运行时库也存在有JavaScript版本(甚至有工具能直接将其他脚本语言的代码,直接转换成JavaScript)。目前通过使用Node.js,JavaScript在现有的脚本语言框架中的性能是相对好的。
因为node-webcl的限制要比浏览器少,所以相关应用的开发进程通常会更快,并且性能还不错。由于Node.js的原因,也有很多动态和多线程应用也会使用JavaScript开发,不过这些应用可能不会在浏览器端使用。这些应用就是典型的服务器端应用,其需要在当前平台上的所有支持OpenCL的设备上,对复杂的负载进行调度。
随着Node.js和node-webcl的使用,基于JavaScript的应用可以快速的部署在服务器端和客户端。当前,一些数据敏感的实时应用,已经可以使用JavaScript完成。
目前,一个新的Node.js模块出现,其名为node-opencl[6]。其与node-webcl为同一个开发者,node-opencl是对node-webcl的重写。node-opencl要比node-webcl更加底层,其可以让JavaScript直接使用OpenCL的特性。WebCL只支持OpenCL 1.1,不过node-opencl支持所有版本的OpenCL。其他人可以使用JavaScript在node-opencl的基础上开发出自己的WebCL。不过,所有WebCL实现都会随着时间的推移,对特性进行增强,对Bug进行修复。所以,目前node-opencl和node-webcl都被Node.js所支持。
[2] https://github.com/Motorola-Mobility/node-webcl
[3] http://brew.sh
[4] http://dev.w3.org/html5/websockets