从可以在 MQL5 中编写 OpenCL 程序开始,已经一年多过去了。发现的任何 OpenCL 设备的条目,现在都可以在 MetaTrader 5 终端启动时在“日志”中看到,如下所示。
这种情况下,MetaTrader 5 终端探测到了直接从某个 MQL5 程序启动 OpenCL 的 4 种方法:一种显卡来自 NVIDIA (OpenCL 1.1),另一种来自 AMD (OpenCL 1.2),根据安装的驱动程序,还有两个 Intel Core-i7 CPU 工具选项。如果您的计算机已有一个适用的 1.1 或更高版本的 OpenCL 设备,您可以放心地略过描述部分,直接前往性能对比,从而亲眼见证允许并行计算给各种任务带来的性能增益。
但是,尝到在其 EA 交易、指标或脚本中使用并行计算甜头的用户并不太多,因为他们不清楚有哪些新的可能、也不具备所需的知识。
问题在于,启动任何使用 OpenCL 的 MQL5 程序,都要求安装相应的软件。正因如此,有大量的用户都不能运行 Mandelbrot 系列脚本,还有 MQL5.community 论坛中的许多其它可用程序。
本文中,我们会向您介绍如何将 OpenCL 安装到您的计算机,这样您就能够亲眼看到在 MQL5 中使用并行计算的巨大优势了。我们不会研究为 MQL5 中的 OpenCL 编写程序的详情,因为网站上已有两篇一流的文章讲述了这一主题:
OpenCL 是由 Khronos Group 集团于 2008 年开发的并行编程开放标准。这一标准允许您利用异构系统中的不同架构,开发可以在 GPU 或 CPU 上并行运行的应用程序。
换而言之,OpenCL 使得计算某任务时运用所有 CPU 核心或 GPU 的庞大运算能力成为了可能,并由此缩短了程序的执行时间。因此处理大工作量和资源消耗大的计算等相关任务时,使用 OpenCL 非常有利。
举个例子,说到 MQL5,处理某个按多交易品种和时间框架对历史数据执行复杂且冗长分析特定脚本时,绩效增益极其可观 (要注意的是,打算采用并行执行的 MQL5 程序,应利用 OpenCL API 以特殊方式编写)。
MQL5 中对于 OpenCL 的支持始于 2010 年 6 月发布的 1.1 版本。所以,为了使用并行计算,您需要拥有一种适合此标准的较新的软件和硬件。
也就是说,要注意的是,开始使用 OpenCL 之前,您的 PC 上有无显卡并不太重要 - 一个 CPU 就够了。这就意味着,OpenCL 几乎适用于每一位想要缩短其 MQL5 程序执行时间的用户。
在分布式运算速度方面,CPU 当然远远落后于其对手-显卡。但是,优秀的多核 CPU 在实现速度大幅提升方面也算不错。我们回到讨论的主题上来。
前面提过,对于并行计算,您既可以用显卡,亦可用 CPU。市场中的相关设备生产商主要有三家:Intel、AMD 和 NVidia。下表中列出的,就是这三家生产商支持 OpenCL 1.1 的设备和操作系统的相关信息:
生产商 | 设备 | 操作系统 |
---|---|---|
Intel | CPU: Core i3, i5, i7 - 用于 PC; Xeon - 用于服务器; Xeon Phi - 用于协处理器 (了解更多)。 |
Windows 7, 8; openSUSE; Red Hat. |
AMD | 显卡: 6400 系列及以上版本的 AMD Radeon HD 显卡; 5400 系列及以上版本的 ATI Radeon HD 显卡; ATI FirePro 显卡 A300、S、W、V 系列; 5400 系列及以上版本的 ATI Mobility Radeon HD; ATI FirePro M7820 M5800 (read more)。 基于 K8 及更新架构的 CPU: Opteron、Athlon 64、Athlon 64 FX、Athlon 64 X2、Sempron、Turion 64、Turion 64 X2、Phenom、Phenom II (了解更多)。 APU (混合型 CPU/GPU 处理器): A、C、E、E2、G、R 系列 CPU。 |
Windows Vista SP2, 7, 8; openSUSE 11.x; Ubuntu 11.04; Red Hat 6.x。 |
NVidia | GPU (带有 CUDA 架构): Tesla、Quadro、GeForce (了解更多)。 |
Windows XP、Vista、7、8 Linux 以及 Mac 操作系统 (了解更多) |
确保您的计算机上至少有一种可用设备(CPU 或 GPU),而且已安装的操作系统要支持 OpenCL 1.1。如已满足上述要求,您则可以放心地前往下一部分-讲解不同硬件生产商的 OpenCL 设置方式。
如果您的计算机上已经安装了必要的软硬件,要开始使用 MetaTrader 5 中的并行计算,您需要做的只是为自己的一个设备设置 OpenCL。
根据您打算使用的硬件 - GPU 或 CPU,OpenCL 的设置流程会有所不同。如果 MetaTrader 5 终端发现支持 OpenCL 的显卡,您只需将其驱动程序升级为最新版本。
只有在您的计算机没有相应的显卡时,才需要安装针对 CPU 的 SDK。
重要须知: 如果您装有带 OpenCL 支持的显卡,则无需为 CPU 的 OpenCL 模拟安装什么软件版本!
除非是试验要求,否则 OpenCL 显卡所提供的优势根本勿庸置疑。
下述几个段落,将根据生产商分别讲解 OpenCL 的设置流程。您可以通过相应的链接访问相关的设置说明:
为了能在 Intel CPU 上使用 OpenCL,您需要下载并安装 Intel SDK for OpenCL Applications (OpenCL 应用程序 Intel 软件开发套件)。为此,请访问开发商的官网下载页面。
图 1.1.OpenCL 专用 Intel SDK 下载页面
您可以在这里找到有关 OpenCL 的一般信息,以及可供下载的产品列表。要下载可用产品,请单击页面右上角的 Compare and Download Products (对比并下载产品)按钮。
图 1.2.可用产品与安装要求相关信息
单击后,您会看到一个窗口,其中包含支持处理器类型和操作系统的产品要求相关信息。选择并通过单击产品图标上方的 Download (下载)按钮下载适用产品。
图 1.3.SDK 下载链接
会有另一个带下载链接的窗口弹出。选择 32 位或 64 位的 SDK 并下载。稍等几分钟,待下载结束后,运行得到的文件。确认 SDK 组件的安装,并将文件解压缩到一个文件夹中。
图 1.4.开始 OpenCL 专用 Intel SDK 的安装
您会看到安装窗口出现 Intel SDK for OpenCL Applications,支持 OpenCL 1.2。单击 Next (下一步),并遵循安装说明。
图 1.5.接受终端用户许可协议
接受《许可协议》的条款和条件。此后,窗口中就会出现待安装的组件 - 单击 Next 继续。
图 1.6.SDK 与 Visual Studio 的集成
如果您的 PC 上已装有 Microsoft Visual Studio 2008 软件(或更新版本),为方便 OpenCL 使用,会提示您与其集成。之后,您只需要选择能够访问已安装组件的用户,指定 SDK 安装位置并单击 Install (安装)。
图 1.7.安装
安装过程将持续几分钟。成功完成后,屏幕上即会出现结果。单击 Finish (完成)以完成安装进程。
图 1.8.完成安装
要安装某 AMD 显卡专用的 OpenCL,我们要将其驱动程序升级到最新版本。可通过驱动程序 下载页面完成。
图 2.1.1. AMD 驱动程序下载页面
如果您知道显卡规格,那么填写页面左侧的表单,即可轻松找到驱动程序。于所有表单字段中选好必要选项后,请单击 Display Results (显示结果)以查找相应的驱动程序。
图 2.1.2. AMD 驱动程序下载
该系统会在 Catalyst Software Suite (驱动程序软件套装)中提供几种驱动,其中就包括 OpenCL 驱动程序。下载驱动程序并运行得到的文件。
图 2.1.3. 确认显卡类型和驱动版本的应用程序下载页面
您也可以通过单击页面右上角的对应链接,使用 Driver Autodetect (驱动程序自动检测)系统(图 2.1.1.)。会提醒您下载 AMD Driver Autodetect 应用程序 - 照此下载并启动该程序。
图 2.1.4. 检测并下载适用驱动的应用程序
该应用程序会对系统进行分析,并允许您下载适合的显卡驱动。下载该应用程序并运行得到的文件。Install Manager (安装管理器)会让您选择将文件解压的目标文件夹 - 选定并单击 Install。
图 2.1.5. AMD 驱动程序安装管理器
弹窗中会出现一份《终端用户许可协议》。我们需要接受其条款和条件。之后,我们选择 Express (快速)安装,指定 AMD 驱动程序的安装位置,再单击 Next。
图 2.1.6. 安装
安装过程将持续几分钟。完成后,屏幕上即会显示相关消息。
图 2.1.7. 完成安装
要为 AMD CPU 安装 OpenCL,我们需要下载并安装最新版本的 AMD APP SDK。为此,请访问开发商官网上的 下方页面。
图 2.2.1. AMD APP SDK 下载页面
此页面会提供一些 SDK 相关信息,并对 OpenCL 进行说明。这里需要我们找到并单击描述下方的 Go to Downloads (前往下载)链接。
图 2.2.2. 可供下载 SDK 表
在页面的底部,您会看到一个表,其中包含各种操作系统(32 位或 64 位)最新的 SDK 版本以及下载链接列表。单击相应链接以选择需要的版本。您会看到《终端用户许可协议》页面。接受协议开始下载。
运行下载的安装程序后,会提示您将安装文件解压到某个文件夹。之后,就是安装上述包含您的 CPU 专用的 AMD APP SDK 的 AMD 驱动程序。而驱动程序的安装流程,请见上文 2.1 节的图 2.1.5 - 2.1.7。
如果您有一个 NVidia 显卡,那么您需要将其驱动程序升级到最新版本,才能安装 OpenCL。您可以在开发商网站上的驱动程序 下载页面下载。
图 3.1.NVidia 驱动下载页面
此页面会为您提供相关选项,手动或自动查找所需驱动程序。如用手动选项,您需要选择产品类型、序列、操作系统并单击 Search (搜索)。系统会找到适合您显卡的最新驱动程序,并提醒您下载。
图 3.2.选定驱动程序下载
如您选择了选项 2,则需要单击 Graphics Drivers (显卡驱动),之后就会要求您利用 GPU_Reader Java 应用程序扫描您的系统。
图 3.3.运行此应用程序,以确定显卡类型和驱动版本
单击 Run (运行)运行此应用程序。等待几秒,即能看到显卡相关信息、安装驱动的当前版本以及推荐的最新驱动版本。单击 Download 进入下载页面,如图 3.2. 所示。
图 3.4.自动识别显卡类型与驱动版本的结果
单击 Download Now (马上下载),并单击 Agree and Download (同意并下载)按钮接受《 NVidia 软件许可协议 》。
图 3.5.接受许可协议并下载驱动程序
由此,我们得到了显卡的最新版本驱动程序。之后,我们运行得到的文件 - 会要求您将驱动安装文件解压到某个文件夹中。解压后即开始安装。首先,您需要再一次接受《NVdia 软件许可协议》的条款和条件。
图 3.6.安装第一阶段,接受《许可协议》
之后,选择 Express 安装选项,并单击 Next。此外,您还可以选择安装 NVidia Experience 附加程序。
图 3.7.选择安装选项
之后,驱动程序立即开始安装,同时还有 NVidia 最新动态的相关宣传。
图 3.8.安装
就这些了。驱动程序安装完毕,我们只需重启系统,即可在 MetaTrader 5 中使用 OpenCL 了。
图 3.9.完成安装
OpenCL_Sample.mq5 专为展示 MQL5 中使用 OpenCL 的诸多优势而编写。它会计算某些组中两个变量的函数值,并利用图形标签 (OBJ_BITMAP_LABEL) 在图表窗口中显示结果。有两种计算方式 - 使用 OpenCL 和不使用 OpenCL。而这些代码块也分别以 WithOpenCL() 和 WithoutOpenCL() 函数的形式实施:
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //... Print("\nCalculations without OpenCL:"); WithoutOpenCL(values1,colors1,w,h,size,const_1,const_2); //--- calculations with OpenCL Print("\nCalculations with OpenCL:"); WithOpenCL(values2,colors2,w,h,size,const_1,const_2); //... } //+------------------------------------------------------------------+ //| Calculations without using OpenCL | //+------------------------------------------------------------------+ void WithoutOpenCL(float &values[],uint &colors[],const uint w,const uint h, const uint size,const uint const_1,const uint const_2) { //--- store the calculation start time uint x=GetTickCount(); //--- calculation of function values for(uint i=0;i<h;i++) for(uint j=0;j<w;j++) values[i*w+j]=Func(InpXStart+i*InpXStep,InpYStart+j*InpYStep); //--- print the function calculation time Print("Calculation of function values = "+IntegerToString(GetTickCount()-x)+" ms"); //--- determine the minimum value and the difference between //--- the minimum and maximum values of points in the set float min,dif; GetMinAndDifference(values,size,min,dif); //--- store the calculation start time x=GetTickCount(); //--- calculate paint colors for the set uint a; for(uint i=0;i<size;i++) { a=(uint)MathRound(255*(values[i]-min)/dif); colors[i]=const_1*(a/16)+const_2*(a%16); } //--- print the paint color calculation time Print("Calculation of paint colors = "+IntegerToString(GetTickCount()-x)+" ms"); } //+------------------------------------------------------------------+ //| Calculations using OpenCL | //+------------------------------------------------------------------+ void WithOpenCL(float &values[],uint &colors[],const uint w,const uint h, const uint size,const uint const_1,const uint const_2) { //--- variables for using OpenCL int cl_ctx; int cl_prg; int cl_krn_1; int cl_krn_2; int cl_mem_1; int cl_mem_2; //--- create context for OpenCL (selection of device) if((cl_ctx=CLContextCreate(CL_USE_ANY))==INVALID_HANDLE) { Print("OpenCL not found"); return; } //--- create a program based on the code in the cl_src line if((cl_prg=CLProgramCreate(cl_ctx,cl_src))==INVALID_HANDLE) { CLContextFree(cl_ctx); Print("OpenCL program create failed"); return; } //--- create a kernel for calculation of values of the function of two variables if((cl_krn_1=CLKernelCreate(cl_prg,"Func"))==INVALID_HANDLE) { CLProgramFree(cl_prg); CLContextFree(cl_ctx); Print("OpenCL kernel_1 create failed"); return; } //--- kernel for painting points of the set in the plane if((cl_krn_2=CLKernelCreate(cl_prg,"Grad"))==INVALID_HANDLE) { CLKernelFree(cl_krn_1); CLProgramFree(cl_prg); CLContextFree(cl_ctx); Print("OpenCL kernel_2 create failed"); return; } //--- OpenCL buffer for function values if((cl_mem_1=CLBufferCreate(cl_ctx,size*sizeof(float),CL_MEM_READ_WRITE))==INVALID_HANDLE) { CLKernelFree(cl_krn_2); CLKernelFree(cl_krn_1); CLProgramFree(cl_prg); CLContextFree(cl_ctx); Print("OpenCL buffer create failed"); return; } //--- OpenCL buffer for point colors if((cl_mem_2=CLBufferCreate(cl_ctx,size*sizeof(uint),CL_MEM_READ_WRITE))==INVALID_HANDLE) { CLBufferFree(cl_mem_1); CLKernelFree(cl_krn_2); CLKernelFree(cl_krn_1); CLProgramFree(cl_prg); CLContextFree(cl_ctx); Print("OpenCL buffer create failed"); return; } //--- store the calculation start time uint x=GetTickCount(); //--- array sets indices at which the calculation will start uint offset[2]={0,0}; //--- array sets limits up to which the calculation will be performed uint work[2]; work[0]=h; work[1]=w; //--- calculation of function values //--- pass the values to the kernel CLSetKernelArg(cl_krn_1,0,InpXStart); CLSetKernelArg(cl_krn_1,1,InpYStart); CLSetKernelArg(cl_krn_1,2,InpXStep); CLSetKernelArg(cl_krn_1,3,InpYStep); CLSetKernelArgMem(cl_krn_1,4,cl_mem_1); //--- start the execution of the kernel CLExecute(cl_krn_1,2,offset,work); //--- read the obtained values to the array CLBufferRead(cl_mem_1,values); //--- print the function calculation time Print("Calculation of function values = "+IntegerToString(GetTickCount()-x)+" ms"); //--- determine the minimum value and the difference between //--- the minimum and maximum values of points in the set float min,dif; GetMinAndDifference(values,size,min,dif); //--- store the calculation start time x=GetTickCount(); //--- set the calculation limits uint offset2[1]={0}; uint work2[1]; work2[0]=size; //--- calculation of paint colors for the set //--- pass the values to the kernel CLSetKernelArg(cl_krn_2,0,min); CLSetKernelArg(cl_krn_2,1,dif); CLSetKernelArg(cl_krn_2,2,const_1); CLSetKernelArg(cl_krn_2,3,const_2); CLSetKernelArgMem(cl_krn_2,4,cl_mem_1); CLSetKernelArgMem(cl_krn_2,5,cl_mem_2); //--- start the execution of the kernel CLExecute(cl_krn_2,1,offset2,work2); //--- read the obtained values to the array CLBufferRead(cl_mem_2,colors); //--- print the paint color calculation time Print("Calculation of paint colors = "+IntegerToString(GetTickCount()-x)+" ms"); //--- delete OpenCL objects CLBufferFree(cl_mem_1); CLBufferFree(cl_mem_2); CLKernelFree(cl_krn_1); CLKernelFree(cl_krn_2); CLProgramFree(cl_prg); CLContextFree(cl_ctx); }
此脚本执行几秒钟后,您就能够在图表窗口中看到上色的一组函数值。其中每一个都对应输入参数中选择的一个色调(红、绿或蓝)。
针对平面中以 0.1 的步幅从 -22 到 22 一组点的脚本执行结果。
除图像本身外,两种方法的函数计算时间也都显示于 EA 交易的日志中,如此一来,您就可以清楚地看到在 MQL5 中使用 OpenCL 的优势和实用价值了。加大步进值,并获取脚本执行结果:
函数计算结果和采用两种方法的上色值。
采用 OpenCL 的 CPU 上的函数计算总时长,看上去短了 5 倍多,而且还远远没到极限!众所周知,在支持 OpenCL 的高级 GPU 上计算,要比 CPU 上计算快得多。而这一事实,可以在不同 OpenCL 设备上执行脚本的结果得到明确证实,如下表所示:
OpenCL 设备 |
未采用 OpenCL 的执行时间,毫秒 |
采用 OpenCL 的执行时间,毫秒 |
性能增益 |
---|---|---|---|
AMD Radeon HD 7970 | 20,361 毫秒 |
171 毫秒 |
119.07 倍 |
NVidia GeForce GT 630 |
24,742 毫秒 |
578 毫秒 |
42.8 倍 |
Intel Core i5 430M |
27,222 毫秒 |
5,428 毫秒 |
5.01 倍 |
AMD Athlon X2 Dual-Core QL-65 |
45,723 毫秒 |
9,516 毫秒 | 4.8 倍 |
可以看出,在顶级 AMD 显卡上使用 OpenCL,让计算时间足足缩短了 100 倍!在稍老一些的 2011 款 GeForce GT 630 上,结果也很显著,时间缩短 42 倍。来自 Intel 和 AMD 的 CPU 被排到最末。但是,其所实现的性能增益,在处理复杂计算时亦非常有利。
就是这样。对比表展示出了在大批量数据处理过程中使用并行计算的明显优势。您要做的,也只是为您的显卡或 CPU 安装相应的驱动程序了。
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程