Quantcast
Channel: 英特尔开发人员专区文章
Viewing all 583 articles
Browse latest View live

利用英特尔® Edison 模块建造机器人平台

$
0
0

简介

如果您对机器人感兴趣,现在是建造机器人的最佳时机。  价格公道的基本部件,种类丰富的微控制器平台,随处可见的在线论坛支持,这些因素使机器人变得平民化,人们可以凭借兴趣自己动手组装机器人。  本文研究了机器人领域的一个激动人心的新增部件,该部件由 DFRobot* 开发,请点击 DFRobot.com获取该部件。  该部件被称为“Devastator”,是一种它具备机器人移动坦克平台,能够出色地实现基本功能,如到处移动和检测对象。 它也具备一些高级特性,例如拍照后自动上传至云!  英特尔® Edison 模块的新增部件是设备“大脑”的最佳选择,能够提供图像分析所需的处理能力,可以通过蓝牙*远程控制,甚至可以通过 Wi-Fi* 连接至互联网。 

 

组装 Devastator 机器人

在开始之前,请务必验证并熟悉所有部件,并预留 2 到 3 个小时的时间完成项目。  网上的说明非常简单明了,但是需要集中注意力。 

请准备以下部件:

  • 一个 2 - 4 毫米的小型十字螺丝刀和平头螺丝刀。
  • 一个活动扳手或尖嘴钳。 

首先需要下载 Devastator 说明,请访问 https://www.dfrobot.com/(搜索 Devastator)。  选择 Edison 版本。  截止本文撰写之时,部件编号为 #ROB0125。

连接电机的英特尔 Edison 机器人坦克内部图

组装之后,通过这个业余技能水平项目,您将更深入地了解基本机器人结构。 最终,您能够熟练组装通用坦克底盘的轴、轮、电子装置及两种电机。

首先安装轴,然后将两个直流电机连接到履带传动链轮。 在橡胶接触地面前,不要安装履带(连接)。  首次运行前,需要在店铺内进行几项测试。 将轴连接到底座时,建议留出 1 厘米的间隙。  上述内容可参阅说明。

然后,在底板建造电池组和主板。  需要指出的是,请使用塑料压铆螺母柱,防止焊点接触金属。否则会引起接地,对电路造成不可修复的损坏。  将自己接地,或者凭借常识小心使用主板。 

连接 OTG 的英特尔 Edison 机器人内部图最后,连接所有电路,准备实验室台架测试。  记录建造过程中所连接的针脚。  请记住,在 Romeo 开发板中,硬件 PWM(脉冲宽度调制)的针脚数为 3 针、5 针、6 针和 9 针。  将绝缘胶带缠绕在裸露的引线周围,如图片中直流电机上的接线柱。  另外,建议您将所有电线连接在一起,确保没有明线通过接线板接地。

 

 

 

 

下表总结了本项目所选的引角。  突出显示 PWM 针脚:3、5、6 和 9。

数字 GPIO 连接
2存在红外线
3转动架底部旋转伺服电机
4超声波测距仪 (Comp)
5转动架顶部倾斜伺服电机
6蜂鸣器
7左 LED 灯
8右 LED 灯
9超声波测距仪 (Vcc、Gnd 和 PWM)
10空白
11空白
12空白
13空白

建造完成英特尔 Edison 机器人 Devastator 坦克此时,无论是否具有网络摄像头或距离检测支持,您都可以选择继续。  顶部面板通过 4 组 M4 螺母螺栓固定,您也可以继续建造顶部转动架(也被称为 6 脚底座旋转套件)。  顶部部件是底部伺服电机的基座,支持顶部转动架和附加传感器(网络摄像头和距离检测器)旋转。  建造 6 脚底座需要不到半小时的时间。

 

 

 

建造顶部转动架(6 脚)

英特尔 Edison 机器人网络摄像头顶部转动架安装完毕建造转动架时,请不要拧紧螺丝钉,避免接触伺服电机。  底部和顶部伺服电机的设计导致这个错误很常见。 请再次熟悉坦克的整体结构,了解所有的工作部件。  收尾之前,再次检查电线是否正确连接。   如果选择使用顶部转动架,建议使用外加电源输入插座。  这样,可以稳定伺服电机的额外功耗,满足更高的功率突增要求(使用 Wi-Fi 无线电引起的)。 

 

 

 

机器人基础知识


在启动机器人之前,让我们回顾机器人基础知识,以了解其内部原理,加深对机器人电子学的基本认识。

 

电压与电流

微控制器与附属组件的额定电压通常为 5.0 伏或 3.3 伏,额定电流不足 1 安培。  电压表示任何指定时间内通过设备的潜在电量。  在处理电子设备时,有必要了解电压和电流的不同,避免毁坏设备。 

微控制器主板的输入电压为 9 - 12 伏,甚至更高,然而,对于每个连接至主板的组件,工作额定电压与最大额定电压低很多。  通过微控制器主板上的降压型转换器将电压降至安全等级。  电压高于设备的额定电压时,设备将烧毁,遭受潜在破坏。  面向英特尔® Edison 模块的 Romeo 开发板已经配备了降压型电压转换器。  如欲了解更多信息,请访问维基百科*: https://en.wikipedia.org/wiki/Voltage_regulator_module

电压表示潜在电量,电流表示任何指定时间内,实际通过设备的电量。  您可能听过一句话“造成生命危险的是电流,而不是电压。”  根据定义,电压只是电源(如墙、电池)一端的潜在电量。  只有形成电路,才会有电流经过。电流流速通常受第三个因素控制 - 电阻。

电流 = 电压除以电阻公式

电路的最常见介质是铜线,电阻极低,1 英寸的铜线电阻只有 8.82e - 6 欧姆。  相比之下,人类皮肤在最极端条件下(潮湿环境中)的电阻是 1000 欧姆。  人类能感知 0.001 安(1 毫安)左右的电流,10 毫安的电流将引起肌肉收缩。  因为多数微控制器将电压限制在 20 伏以内,如此低的电流中工作不会产生安全隐患。

 

功耗

为了维持运转,所有组件需要使用(消耗)一定的电流。  如果施加了额外负载,电机对电流的需求将增加。  因此,直流电机特别需要一个外加电源,电源电压应高于 LED、传感器等其他组件。  使用直流电机时,一定要配备电机控制器和二极管保护装置,避免开关电机时出现反电动势。  如欲了解有关此话题的更多详细信息,可以在线搜索 “直流电机”与“反电动势”。 

常见电压与电流范围示例:

设备 / 组件直流电压最小 / 最大电流
英特尔® Edison 模块7 伏 - 15 伏1 安输入
  200 毫安消耗(开启 Wi-Fi 时达到 600 毫安)
英特尔® Edison GPIO Pin   @3.3 伏1.8 伏 - 3 伏输出24 毫安
英特尔® Edison GPIO Pin       @5 伏1.8 伏 - 3 伏输出32 毫安
常见 LED1.8 伏 - 4 伏20 毫安
有刷直流电机6 伏 - 9 伏取决于堵转电流

 

制动器

制动器受微控制器控制。  常见制动器包括电机、LED 与蜂鸣器。  每种设备对这些组件的控制方式各不相同。  例如,通过连接与限流电阻器相结合的 GPIO 针,可以开启或关闭 LED。  只需让电流通过二极管,二极管便会发光。  电流越多,二极管越亮。  然而,脉冲宽度调制 (PWM) 技术可以有效控制电机,该技术以快速切换开关的方式控制输入电机的电压。 

PWM 基础知识

直流电机没有连续流动的电流。  它采用脉冲宽度调制 (PWM) 技术,能快速打开或关闭电流。  使用 PWM 时,电机开启时间由基础信号(以特定频率振荡)和“工作周期”(波振荡时信号频率较高(开启)的总时间)控制。  如果已知基于硬件的定时器产生 1 赫兹(每秒一次)的频率,将工作周期设置为 0.5,灯会闪烁(开启 0.5 秒,关闭 0.5 秒)。  将信号开启的时间设置为 1 秒时,灯闪烁的频率会降低。

Pulse Width Modulation, Duty Cycle Half

Pulse Width Modulation, Duty Cycle 1

伺服电机

伺服电机和直流电机工作原理相似,但是前者拥有准确的位置精度,能在特定位置停止并保持不动。  如欲获取有关伺服电机的详尽介绍,请访问:  伺服电机简介

传感器

PIR 传感器与被动红外检测器检测对象存在和感知对象距离的能力使机器人更加智能。  PIR(被动红外)利用标准 GPIO 针脚,可以用于检测电磁场的变化。  由于所有物体都会发出辐射,这个敏感的设备甚至能够检测出细微的光线变化。  https://en.wikipedia.org/wiki/Passive_infrared_sensor

 

另一个非常出色的传感器是超声波测距传感器(一种距离指示器)。  该传感器使用超声波超声波测距仪测量对象的距离,通过对象反射回来的声波来检测返回时间。  和警用雷达速度检测器上的老式雷达相似,但是有所不同,传感器使用的是声波,而非无线电波。  这个设备价格便宜,但是只能用于短距离测距,而且周围环境必须清洁,不能有灰尘或雪。

 

 

了解面向英特尔® Edison 模块的 Romeo 开发板

Romeo 开发板为 Devastator 机器人大脑提供多种能力,如移动电机、感知环境和开关指示灯的能力。  该平台包含 14 个 GPIO 针 (4 个 PWM)、内置 H 桥电机驱动程序、SPI 与 I2C 功能、针对外部电源连接的专用连接和一个英特尔® Edison 模块,是一个支持入门级移动机器人项目的强大开发板。  这个平台的优势是它的可扩展性。 底盘性能出色,可以随意在上面添加或安装外加电源与组件。  如欲获取更多信息,请访问 DFRobot.com,下载 Romeo 开发板的完整示意图

Romeo Intel Edison Board Schematic

电源

DFRobot* Devastator 套件配备的标准电池组是 6x1.5 v AA 电池组,总源电压为 9 伏。  最大输入电压能够支持高达 12 伏的外加电源输入。  需要注意的是,尽管外加电压可以作为输入电压,但是在任意指定时间,开发板为 GPIO 针提供 3.3 伏电压,还要为电机控制器电路提供单独的控制电压。  可以连接标有“伺服电源”的单独电源插座,为伺服控制提供外加电源。  如果整个平台只在 9V (AA x 6) 电池组上运行,并行操作(如直流电机定向移动、伺服电机平移和 Wi-Fi 上传激增)几乎耗尽 9V 电池组的电量。  直流电机驱动程序自身需要的恒定电流是每个电机 2 安。  提前了解了这些,强烈建议您购买可充电电池。  坦克开启后,将在短距离内迅速耗尽 AA 标准碱性电池中额定 2,500 毫安的电量。  可以添加一组 9 伏可充电电池,输入电压将达到 18 伏。  此外,针对伺服电机插座的单独输入电源也是非常不错的选择,为开发板提供外加电源,减少主输入的电流功耗。  如果选择连接伺服输入,不要高于伺服电机和连接设备的输入电压。

电机控制

如示意图所示,直流电机连接至电源输入插座附近,直接连接至 H 桥驱动程序 IC(该驱动程序 IC 执行前向运动和反向运动所需的电压偏置)。  英特尔® Edison 模块是开发板的主要控制器,电机控制器 IC 实际由一个 Atmel ATMega8 MCU 驱动。  伺服电机分别连接至 GPIO 轨 PWM 专用针脚,通过计时信号驱动(和其他伺服控制一样)。  如上文所述,如果选择为伺服输入补充额外电压,不要高于伺服电机的输入电压。

数据与串行连接

相对于输入电源,开发板的另一端是 micro-USB 连接。  带有 COM 标记的串行连接可能是您使用的第一个连接。  该端口支持连接至英特尔® Edison 模块,启动终端 shell 会话,进而配置 Edison,连接 Wi-Fi,甚至在外壳内配置并下载附加软件组件。  但是不能进行数据传输。第二个连接是 USB/OTG 连接,主要用于上传 Arduino* 风格方案至开发板。  建议您连接线缆,在工作台测试时断开与电脑的连接。  由于是物理连接,多次插入和拔出增加损坏输入端口的风险。  最初的测试将频繁地连接与断开,所以建议使用电脑的连接,而不是开发板的微型连接。 

有一个附加连接值得一提 - FTDI 连接。  需要更新开发板上的 ATMega8 固件,以解决 I2C 稳定性方面的已知问题。  更新对保证直流电机正常运转非常必要,会在后面的章节介绍。

固件编码

为了设备的有效运转,必须创建软件,并上传至英特尔® Edison 模块。  可以采用多种不同方法。

Intel Edison Software Stack

首先,因为英特尔® Edison 模块运行 linux* 操作系统 (Yocto Linux),一种方法就是编写一个 C、C++ 或 Python* 程序,并在操作系统上直接运行(和其他在 Linux 操作系统上运行的应用相同)。  社区里已经存在许多库,可以获取英特尔® Edison 模块上的所有硬件。  可以免费安装库(如简单的 GPIO 针访问、Wi-Fi 与 Bluetooth),并利用库编码。  只需编写一个程序,运行标准 make 程序,便可创建可执行程序。

在 Edison 模块编程的第二种方法是使用大家所熟悉的 Arduino* 库和 IDE,本文对第二种方法进行了详细说明。  利用 Arduino 编程非常简单,通过 CLLoader Arduino 仿真器(一个运行在 Linux 操作系统上的服务)即可在英特尔® Edison 模块上编程。  英特尔® Edison 模块上,该服务设置为默认运行,无需上传或运行 Arduino 方案。  和其它 Arduino MCU 兼容性平台相同,只需连接到开发板,并上传方案。  可以通过简单的 ps 命令来验证 clloader 程序是否在 Linux shell 中运行。

Intel Edison CLloader

使用 Arduino 开始编程前,请访问 https://www.arduino.cc/en/Main/Software,以下载最新版 Arduino IDE。


最后,最新版英特尔 XDK® 支持通过 Wi-Fi 上传方案。  XDK 使用的开发语言是 Node JavaScript* (Node.JS*),在现有库和封装器中不断发展。  编译并上传应用至守护程序,后者在英特尔® Edison 模板上直接运行,运行方式和 Arduino 方案相似,但是通过不同的服务。

设置

英特尔 Edison Romeo 数据连接

在进行外设测试前,首先确保所有固件是最新版,并且安装了驱动程序。  连接至 COM 端口(不是 OTG 端口),确保其可见。通过执行 Windows* 的“设备管理器”,并导航至端口,以纠正串行 COM 端口上的波特率。 该连接是默认串行连接,可以用于远程访问设备,并运行一个 Linux shell 会话。

 

 

Intel Edison Setup Serial Connection in Windows

然后,连接至数据 OTG 连接。  通过该连接,将方案与代码更新为英特尔® Edison 模块。

Intel Edison Data Connection in Windows, COM Port Setup

下载英特尔® Edison 模块的相关软件

驱动程序与设置
https://software.intel.com/zh-cn/iot/hardware/edison/downloads

Flashtool 固件
https://software.intel.com/zh-cn/using-flash-tool-lite

最后,下载最新版 Poky 映像,运行 flashtool,并利用最新版 Linux 映像更新英特尔® Edison 模块。
https://software.intel.com/zh-cn/iot/hardware/edison/downloads

 

通过 FTDI 连接更新 ATMega8* MCU
通过本次更新,将获取最新版 ATMega8,确保修复全部 I2C 故障,该故障会引起电机启动问题!
https://www.dfrobot.com/wiki/index.php/Romeo_for_Edison_Controller_SKU:_DFR0350#Atmega8_Firmware_Upgrade

 

利用 PuTTY 配置英特尔® Edison 模块
安装 Putty、英特尔 Edison SSH 连接通过端口识别的串行设置进行连接,并运行 ssh 命令(ssh 作为不带密码的“根”)。  请务必按 enter 键以完成连接。
请点击以下链接下载 PuTTY: http://www.putty.org/ 

运行 “configure-edison -setup”,按照提示完成安装。  在 Wi-Fi 可用的情况下,可以选择连接到 Wi-Fi。

Intel Edison Setup, Edison Shell Configure Edison

 

更新英特尔® Edison 模块,支持方案加载启动 

对于默认脚本加载器,Poky 映像的最新分发包没有正确设置加载器权限。  该步骤强制执行,确保上传的最后一个映像在设备下次开机时执行。  共有 4 个需要上传的文件。

下载更新文件

https://github.com/gameswarp/edison-clloader

备份当前文件,然后利用 WinSCP将下载文件传输到 /opt/edison 文件夹。

Intel Edison CLloader file List

下载 WinSCP:  https://winscp.net/eng/download.php

上传文件后,选择新文件并点击 F9,将 4 个文件更改为可执行文件。

WinSCP File List, CL Loader files, Intel Edison

可以通过 diff 命令来验证新上传的脚本是否产生变化,也可以手动验证。

Intel Edison CLloader DIFF to verify changes

如欲了解有关该流程的更多详细信息,请访问:  https://communities.intel.com/thread/77945

导入 Arduino* 库

Arduino basics 能够连接并识别设备,正确安装开发板驱动程序和库,下载常见库支持,并将其安装到正确位置。

添加库支持非常简单,和查找代码,在 Arduino\library 文件夹中复制文件夹和文件一样简单。  Arduino IDE 还有一个 “Import As Zip” 选项,但是如果库供应商没有遵循正确的流程与结构,这个选项不可用。  最关键的是,将库添加至 Arduino 和在库文件夹中创建文件夹一样简单。  您还会发现,多数库配有示例子文件夹,下一次启动时,将在 Arduino IDE 下的下拉框中显示详细示例。  如欲了解更多信息,请访问以下链接:  https://www.arduino.cc/en/Reference/Libraries 

安装 Arduino IDE

步骤 1:  确保 Arduino IDE 配备有英特尔® Edison 模块 i686 开发板支持。  通过英特尔® Edison 模块的安装程序安装最新版 Arduino 后,将配备该支持。

请确保已经安装了英特尔® Edison 模块 i696 开发板支持: [Tools--►Boards--►Board Manager]

Arduino board Support for Intel Edison

步骤 2:  安装 DFRobot 库

https://github.com/ouki-wang/Devastator-Tank-Mobile-Platform-with-Edison

DevastatorEdison文件夹复制到 Arduino Library 文件夹中。

[SKETCH--►Include Library--►Manage Libraries].

搜索 DFRobot,并单击 Install按钮。

Arduino Library Installation

步骤 3:  运行快速测试

为了验证 DFRobot 库支持是否可用,需要创建快速方案,并引用库提供的类别。  如果代码开始编译,可以进行设备的预发布测试。  如果代码没有开始编译,重启 Arduino IDE 或手动验证库是否正确安装。

#include <DFRobot.h>
#include <IIC1.h>

DFrobotEdison leftMotor;
void setup() {}
void loop() {}

预发布测试


在发布测试版 Devastator 机器人前,建议对一系列基本框架测试进行编码,确保功能正常。  预先执行稳定可以尽早确认缺陷,缩短今后特性开发的周转时间。 

基本测试

  • 控制电机 - 前进、后退、左转与右转
  • 开启灯
  • 开启蜂鸣器
  • 对象检测

总的来说,请务必缓慢运行测试,验证了较小范围内操作后,才能全速或全角运行电机。  本项目测试案例集应当确保每一个组件可操作。  将输出预期行为的 Serial.print() 命令添加至记录控制台,这样做非常有用。  提前完成上述操作将增加您在环境中运行的信心。  DFRobot 套件(电气零件配件盒)中有一个组件,轮间隙较大,非常适合用作底座。不管是否连接履带,都可以进行 DFRobot 预发布测试。

Intel Edison Robotics Tank DFRobot Devastastor Constructed

示例 API

  • IsObjectDetected()
  • SoundBuzzer()
  • FlashLights()
  • StopMotors()
  • TurnLeft()
  • TurnRight()
  • SetDirection()
  • GoStraight()
  • TurnAround()
  • Backup()
  • StartupWarning()

 

传感器测试

/*
* This example will test the following items:
*  - PIR Sensor
*  - Left and Right LEDs
*  - Buzzer
*  OVERVIEW:
*    On Presence, flash lights and emit tone.
*    Tone should change each time PIR is triggered
*
*   Matt Chandler
*   Intel, Corp.
*   December 2016
*/

byte presencePin = 2;
byte leftLED = 7;
byte rightLED = 8;
byte buzzerPin = 6;
bool buzzerOn=true;

void setup() {
pinMode(presencePin, INPUT);
pinMode(leftLED, OUTPUT);
pinMode(rightLED, OUTPUT);
pinMode(buzzerPin, OUTPUT);
Serial.begin(9600);
}

void loop(){

  if (IsObjectDetected())
  {
    flashLights();
    soundBuzzer();
  }
}
bool IsObjectDetected()
{
  return digitalRead(presencePin)==1 ? true:false;
}
void soundBuzzer()
{
  if (!buzzerOn)
    return;
  int delay=200;
  unsigned int buzzerTone = 100;
  for(int i=0;i<4;i++)
  {
    tone(buzzerPin, buzzerTone, delay);
  }
  noTone(buzzerPin);
}
void flashLights()
{
  digitalWrite(leftLED,1);
  delay(200);
  digitalWrite(leftLED,0);
  delay(500);
  digitalWrite(rightLED,1);
  delay(200);
  digitalWrite(rightLED,0);
}

MOTOR TEST

/*
 * Sample DFRobot Motor Tests
 *
 * goStraight(), turnLeft(), turnRight(), stopMotors()
 *
 * Matt Chandler
 * Intel, Corp.
 * December, 2016
*/
#include <DFRobot.h>
#include <IIC1.h>

DFrobotEdison leftMotor;
DFrobotEdison rightMotor;

bool directionToggle = false;
byte currentSpeedRight = 0;
byte currentSpeedLeft = 0;
byte leftLED = 7;
byte rightLED = 8;

byte DIRECTION_LEFT = 0;
byte DIRECTION_RIGHT = 1;

byte startupDelaySeconds = 5;

void setup() {
  leftMotor.begin(M2);
  rightMotor.begin(M1);
  pinMode(leftLED, OUTPUT);
  pinMode(rightLED, OUTPUT);
  Serial.begin(9600);
}

void loop(){
  startupWarning();
  goStraight(150, 2);//speed, distance
  turnLeft(45, 2);
  goStraight(150, 2);//speed, distance
  turnRight(45, 2);
  goStraight(150, 2);//speed, distance
  stopMotors();
  backup(150,2);
}
void startupWarning()
{
  stopMotors();
  Serial.println("");
  Serial.print("Getting ready in ");
  Serial.print(startupDelaySeconds);
  Serial.println(" seconds");
  for (int i=startupDelaySeconds; i > 0; i--)
  {
    Serial.print("");
    Serial.print(i);
    digitalWrite(leftLED,1);
    digitalWrite(rightLED,1);
    delay(500);
    digitalWrite(leftLED,0);
    digitalWrite(rightLED,0);
    delay(500);
  }
  Serial.println("");
  Serial.println("GO!!");
}
void setDirection(const uint8_t dir)
{
    leftMotor.setDirection(dir);
    rightMotor.setDirection(dir);
}
void goStraight(byte speed)
{
  stopMotors();
  setDirection(ANTICLOCKWISE);
  leftMotor.setSpeed(speed);
  rightMotor.setSpeed(speed);
}
void stopMotors()
{
  leftMotor.stop();
  rightMotor.stop();
  delay(1000);
}
void goStraight(byte speed, int durationSeconds)
{
  Serial.println("");
  Serial.println("Going straight");
  currentSpeedRight = speed;
  currentSpeedLeft = speed;
  delay(500);
  goStraight(speed);
  delay(durationSeconds*1000);
}
void backup(byte speed, int durationSeconds)
{
  stopMotors();
  setDirection(CLOCKWISE);
  leftMotor.setSpeed(speed);
  rightMotor.setSpeed(speed);
  delay(durationSeconds*1000);
}
void turnLeft(byte angle, int durationSeconds)
{
  turn(DIRECTION_LEFT, angle, durationSeconds*1000);
}
void turnRight(byte angle, int durationSeconds)
{
  turn(DIRECTION_RIGHT, angle, durationSeconds*1000);
}
void turn(byte direction, byte angle, byte durationMS)
{
  DFrobotEdison motor;
  String directionText;
  byte directionPin;

  //Ensure going straight first
  byte currentSpeed = currentSpeedLeft = currentSpeedRight;

  if (direction == DIRECTION_LEFT)
  {
    directionText = "Left";
    motor = leftMotor;
    directionPin = leftLED;
  }
  else
  {
    directionText = "Right";
    motor = rightMotor;
    directionPin = rightLED;
  }
  delay(500);

  digitalWrite(directionPin,1);
  // Take current right speed and lower left motor by mapped value

  //Convert angle to speed where 0 is straight ahead
  byte newSpeed = map(angle, 0, 90, 0, currentSpeed);
  Serial.print("Turning ");
  Serial.print(directionText);
  Serial.print(" at angle ");
  Serial.print(angle);
  Serial.print("Current Speed: ");
  Serial.println(currentSpeed);
  Serial.print("New speed: ");
  Serial.println(newSpeed);
  delay(250);

  motor.setSpeed(newSpeed);
  Serial.print("Turning ");
  Serial.print(directionText);
  Serial.print(" now for ");
  Serial.print(durationMS/1000);
  Serial.println(" seconds.");
  delay(durationMS);
  digitalWrite(directionPin,0);
  Serial.println("");
}

准备上路

<img a9="" alt="" src=" c8=""="" default="" df="" edison="" files="" https:="" managed="" p="" sites="" software.intel.com="" title="&quot;英特尔机器人、构造" usb="">

英特尔机器人、构造 DF 机器人与英特尔 Edison 机器人您的机器人已经通过了基本测试,现在可以完成组装了。  在执行最后步骤之前,建议您上传一份空白方案或简单的灯光闪烁测试,以避免开启坦克时执行之前的电机代码。  关闭电池,然后谨慎地将履带放置于坦克两侧的链轮。  闪存一份之前创建的测试移动方案,断开 USB 连接,并将您的坦克放到地上。  打开电池开关,开始执行方案!

以下是一个基本方案,帮助您开启探索之旅。  在调转方向前,建议执行 motorOff() 调用,希望您修改代码,并乐在其中。

 

按需行进

/*
 * Sample DFRobot Motor and Lights test
 *
 * Wait for PIR Sensor detection
 * Go Forward
 * Turn Around 2 x 180'
 * Return to position by backing up
 * If object is detected in rear, attempt to go around it by altering angle
 *
 *
 *
 * Matt Chandler
 * Intel, Corp.
 * December, 2016
*/
#include <DFRobot.h>
#include <IIC1.h>

bool testFlag = false;

DFrobotEdison leftMotor;
DFrobotEdison rightMotor;
byte presencePin = 2;
byte leftLED = 7;
byte rightLED = 8;

bool directionToggle = false;
byte currentSpeedRight = 0;
byte currentSpeedLeft = 0;

byte DIRECTION_LEFT = 0;
byte DIRECTION_RIGHT = 1;

byte startupDelaySeconds = 5;

double turnAroundTimeSeconds = 4;
byte turnAroundSpeed = 100;
byte buzzerPin = 6;
bool buzzerOn=true;



void setup() {
  leftMotor.begin(M1);
  rightMotor.begin(M2);
  pinMode(leftLED, OUTPUT);
  pinMode(rightLED, OUTPUT);
  Serial.begin(9600);
}

void loop(){

  stopMotors();
  if (IsObjectDetected())
  {
    startupWarning();
    if(testFlag)
    {
      turnAround();
      stopMotors();
    }
    else
    {
        goStraight(200, 6);//speed, distance
        turnAround(); //180
        goStraight(200, 2);//speed, distance
        turnAround();
        backup(200,8); //Go backwards
        if(IsObjectDetected())
        {
          soundBuzzer();
          backup(200,4);
          Serial.println("Object Detected");
          goStraight(200, 2);//speed, distance
          turnLeft(45, 4);
          turnRight(45, 4);
          goStraight(200, 3);//speed, distance
        }
        turnAround();
    }
  }
}
void startupWarning()
{
  Serial.println("");
  Serial.print("Getting ready in ");
  Serial.print(startupDelaySeconds);
  Serial.println(" seconds");
  for (int i=startupDelaySeconds; i > 0; i--)
  {
    Serial.print("");
    Serial.print(i);
    digitalWrite(leftLED,1);
    digitalWrite(rightLED,1);
    delay(500);
    digitalWrite(leftLED,0);
    digitalWrite(rightLED,0);
    delay(500);
  }
  Serial.println("");
  Serial.println("GO!!");
  soundBuzzer();
}
void setDirection(const uint8_t dir)
{
    leftMotor.setDirection(dir);
    rightMotor.setDirection(dir);
}
void goStraight(byte speed)
{
  stopMotors();
  rightMotor.setDirection(ANTICLOCKWISE);
  leftMotor.setDirection(ANTICLOCKWISE);
  delay(500);
  leftMotor.setSpeed(speed);
  rightMotor.setSpeed(speed);
}
void backup(byte speed, int durationSeconds)
{
  stopMotors();
  rightMotor.setDirection(CLOCKWISE);
  leftMotor.setDirection(CLOCKWISE);
  leftMotor.setSpeed(speed);
  rightMotor.setSpeed(speed);
  delay(durationSeconds*1000);
}

void stopMotors()
{
  Serial.println("Stopping motors");
  leftMotor.stop();
  rightMotor.stop();
  delay(3000);
}
void goStraight(byte speed, int durationSeconds)
{
  Serial.println("");
  Serial.println("Going straight");
  currentSpeedRight = speed;
  currentSpeedLeft = speed;
  goStraight(speed);
  delay(durationSeconds*1000);
}
void turnLeft(byte angle, int durationSeconds)
{
  turn(DIRECTION_LEFT, angle, durationSeconds*1000);
}
void turnRight(byte angle, int durationSeconds)
{
  turn(DIRECTION_RIGHT, angle, durationSeconds*1000);
}
void turnAround()
{
  stopMotors();
  Serial.println("Turning around");
  leftMotor.setDirection(CLOCKWISE);
  rightMotor.setDirection(ANTICLOCKWISE);
  rightMotor.setSpeed(turnAroundSpeed);
  leftMotor.setSpeed(turnAroundSpeed);
  delay(turnAroundTimeSeconds*1000);
  stopMotors();
  Serial.println("Turned around");
  rightMotor.setDirection(ANTICLOCKWISE);
  rightMotor.setDirection(ANTICLOCKWISE);
}
void turn(byte direction, byte angle, int durationMS)
{
  if (angle==90)
  {
    Serial.println("Angle is 90, turning around");
    turnAround();
    return;
  }
  DFrobotEdison turningMotor;
  DFrobotEdison oppositeMotor;
  String directionText;
  byte directionPin;

  //Ensure going straight first
  byte currentSpeed = currentSpeedLeft = currentSpeedRight;

  if (direction == DIRECTION_LEFT)
  {
    directionText = "Left";
    turningMotor = leftMotor;
    oppositeMotor = rightMotor;
    directionPin = leftLED;
  }
  else
  {
    directionText = "Right";
    turningMotor = rightMotor;
    oppositeMotor = leftMotor;
    directionPin = rightLED;
  }
  delay(1000);

  digitalWrite(directionPin,1);
  // Take current right speed and lower left motor by mapped value

  //Convert angle to speed where 0 is straight ahead
  byte newSpeedOfTurningMotor = map(angle, 0, 90, 0, currentSpeed);
  Serial.print("Turning ");
  Serial.print(directionText);
  Serial.print(" at angle ");
  Serial.println(angle);
  Serial.print("Current Speed: ");
  Serial.println(currentSpeed);
  Serial.print("New speed: ");
  Serial.println(newSpeedOfTurningMotor);
  delay(250);
  turningMotor.setSpeed(newSpeedOfTurningMotor);
  Serial.print("Turning ");
  Serial.print(directionText);
  Serial.print(" now for ");
  Serial.print(durationMS/1000);
  Serial.println(" seconds.");
  delay(durationMS);
  digitalWrite(directionPin,0);
  Serial.println("");
  turningMotor.setSpeed(currentSpeed);
  oppositeMotor.setSpeed(currentSpeed);
}
bool IsObjectDetected()
{
  return digitalRead(presencePin)==1 ? true:false;
}
void flashLights(byte seconds)
{
  for (int i=0;i<seconds;i++)
  {
    digitalWrite(leftLED,1);
    delay(200);
    digitalWrite(leftLED,0);
    delay(seconds);
    digitalWrite(rightLED,1);
    delay(200);
    digitalWrite(rightLED,0);
  }
}
void soundBuzzer()
{
  if (!buzzerOn)
    return;
  int delay=200;
  unsigned int buzzerTone = 100;
  for(int i=0;i<4;i++)
  {
    tone(buzzerPin, buzzerTone, delay);
  }
  noTone(buzzerPin);
}

高级策略

机器人已经可以移动了,您可以继续改进 Arduino 代码库中的代码,或者扩展上文提到的不同开发选项。  有一个开发选项将使您直接通过 C 开发或英特尔 XDK® 中的 JavaScript 封装器,深入了解 mraa (读音为 “m-rah”)Linux 库。  迁移至英特尔 XDK® 后,可以通过无线方式对程序进行编程,这个特性非常不错,使您无需连接到设备,便可上传经典 Arduino 方案。  如欲了解更多高级特性,包括 mraa 讨论及 Wi-Fi 摄像头功能,请查看以下其他文章:

 

 

关于作者

Matt Chandler 是英特尔公司的一名高级软件工程师,负责大规模物联网项目的支持工作。

参考资料

Arduino* 下载
https://www.arduino.cc/en/Main/Software

DFRobot* 产品说明
https://www.dfrobot.com/wiki/index.php/Romeo_for_Edison_Controller_SKU:_DFR0350

WinSCP 下载 – 面向安全文件传输
https://winscp.net/eng/download.php

PuTTY 下载 – 确保外壳安全访问 Edison
http://www.putty.org/

被动红外检测 (PID) 传感器 Wiki
https://en.wikipedia.org/wiki/Passive_infrared_sensor

确保保存方案 - 利用 Poky distro 修复已知映像,截至 2016 年 6 月
https://communities.intel.com/thread/77945

伺服电机简介
http://www.sciencebuddies.org/science-fair-projects/project_ideas/Robotics_ServoMotors.shtml

蜂鸣器示例代码
https://www.arduino.cc/en/Tutorial/ToneMelody?from=Tutorial.Tone

USB OTG 连接
https://en.wikipedia.org/wiki/USB_On-The-Go

声明

本文件不构成对任何知识产权的授权,包括明示的、暗示的,也无论是基于禁止反言的原则或其他。

英特尔明确拒绝所有明确或隐含的担保,包括但不限于对于适销性、特定用途适用性和不侵犯任何权利的隐含担保,以及任何对于履约习惯、交易习惯或贸易惯例的担保。

本文包含尚处于开发阶段的产品、服务和/或流程的信息。 此处提供的信息可随时改变而毋需通知。 联系您的英特尔代表,了解最新的预测、时间表、规格和路线图。

本文件所描述的产品和服务可能包含使其与宣称的规格不符的设计缺陷或失误。 这些缺陷或失误已收录于勘误表中,可索取获得。

索取本文件中提的、包含订单号的文件的复印件,可拨打1-800-548-4725,或登陆www.intel.com/design/literature.htm

英特尔、Intel 标识、Intel RealSense 和英特尔实感是英特尔在美国和/或其他国家的商标。

*其他的名称和品牌可能是其他所有者的资产。

**该示例源代码根据英特尔示例源代码许可协议发布。

英特尔公司 © 2016 年版权所有。

 


面向开发人员的人工智能入门

$
0
0

下载 PDF (453kb) 

到现在,计算机科学家对人工智能 (AI) 的不懈探索已有 60 多年。 在这几十年中,该术语的涵义已发生了很多变化,不过最近的研究进展让我们在实现机器智能方面达到了前所未有的高度。

刚刚接触人工智能和机器学习的开发人员会有很多疑问,包括:“我能用人工智能做什么?”或“为何人工智能会是一种编程解决方案?”,“满足哪些必要条件才能让程序具备学习能力?”,“机器交互要达到什么水平才能让其看起来比较智能?”,甚至“我的智能程序需不需要一看上去就很智能?”

 

简介

人工智能 (AI) 是一种出色的解决方案,但也带来了一些问题。 这一探究领域目前正处于快速发展之中,可解决诸如医疗诊断或海底采矿等深奥、复杂的问题。 它还能为我们提供一些娱乐解决方案,如视频游戏中更智能的对手。 开发人员可开发智能解决方案,解决各种疑难问题,帮助塑造智能未来。

 

世界上的人工智能 (AI)

人工智能无疑将在计算行业掀起一场重大变革。 它是游戏、机器人学、医学、交通运输和物联网 (IoT) 等计算领域的根本要素。 现在,人工智能正在向着更深的层面发展,它将像工业革命、技术革命和数字革命那样,为人类日常生活的方方面面带来翻天覆地的变化。

虽然几十年来人工智能一直是计算领域的一部分,但我们仍然处于其初期探索阶段,对于它将来能做什么以及如何为人类所用依然莫衷一是。 下面我们举例说明,随着技术的日益成熟,人工智能将实现哪些功能。

人工智能将加快重大问题的解决速度,解决这些问题将不再需要花费数月、数年乃至几十年的时间。 药物或其它介入治疗等治疗方案将实现深层个性化,即基于个人 DNA 实施。 智能助手将提供有关周围环境的实时信息指导,以预防犯错并创造新机遇。 在商业领域,它将极大程度地降低欺诈检测难度,有时甚至杜绝欺诈。

人工智能将助力科学发现结出新硕果。 科学家将挣脱人体生物学和认知法的束缚,在深海和外太空领域、动物和昆虫界、粒子物理学、以及大脑奥秘等方面挖掘出许多新的深刻见解。

人工智能将完善人类能力。 人机之间的全新共生关系将增强我们的能力,帮助提升医疗诊断的精确性,确保法律指导可囊括判例法的整个历史,且其它服务也会达到前所未有的精确水平。

人工智能将让人们无需再冒险执行驾驶、消防和采矿等令人烦闷的任务。 目前,人工智能刚开始用于自动汽车领域。

 

英特尔促进了人工智能的发展

在英特尔,人工智能并不仅局限于功能层面。 英特尔不是将人工智能看作最终结果和定义人类理解力的方式,而是将其视作解决人类问题的计算工具。 人工智能并非要定义实现人类般智能水平所需的条件,或必须通过什么最低的“智能”水平测试,而是采取四个步骤:感知、推理、行动、适应, 即分析输入(感知),得出结果(推理); 然后根据结果选择适当举措(行动),并根据实施成效改进输入的收集和选择方式,进而改进计算(适应)。

英特尔的四步方案避免了大费周章确定机器是否具备人类智能水平,可单独指导您通过编程创建出色的人工智能解决方案。 当然,除这一方案外,英特尔还提供先进的计算机技术,让复杂计算成为加快人工智能运行速度的必然选择。

 

 

什么是人工智能?

人工智能是一种出色的解决方案,但其仍然具有一个基本问题: 如何判定解决方案的智能性? 业界人士开发了许多测试来确定人工智能展现智能行为的能力是否与人类毫无差别。 其中最著名的测试是图灵测试。 在日常用例中,确定人工智能是否与人类智慧相当是一个学术话题。

尽管这对于了解智能的意义非常重要,但对于人工智能的概念,有一个消费类应用更具实际意义。 解决实际问题是人工智能的关键。 因此,在思考人工智能为何是一种强大工具时,首先必须确保其能够感知推理行动并根据经验进行适应,无论我们使用什么技术创建和利用人工智能,或人工智能的利用范围如何。

感知要求人工智能在海量数据中发现和/或识别有意义的概念或对象, 比如这是肿瘤组织还是正常组织? 这是交通信号灯还是霓虹灯?如果是前者,它是绿色、黄色还是红色?

推理要求人工智能了解更大范围的环境,并制定实现目标的计划。 如果目标是进行鉴别诊断,那么除医疗成像和实验室测试中发现的结果外,机器还必须考虑患者报告的症状、DNA 图谱、病历以及环境影响。 如果目标是避免车辆碰撞,人工智能必须根据车辆行为、距离、速度和道路状况计算撞车的可能性。

行动意味着人工智能推荐或直接启动最佳的行动方案,尽可能实现预期结果。 根据诊断,人工智能可推荐或实施一种治疗方案。 根据车辆和交通分析,人工智能可刹车、加速或准备安全机制。

最后,我们必须能够在每个阶段根据经验调整(人工智能内及人工智能所在计算系统内的)算法,对其进行再训练,以更智能地进行推理。 医疗算法应进行再训练,以更准确地检测疾病,更有效地洞察环境,以及根据以前的结果改进治疗方案。 自动汽车算法应进行再训练,以识别更多盲点,考虑更多的环境变量,并根据以前的事故调整应对措施。

目前,人工智能的最大能力是“感知”,同时其在推理和行动方面的能力也在继续增强。 使用的多数技术都需要数学或统计算法,包括回归、决策树、图论、分类、聚类等,不一而足。 然而,在深度学习领域,有一种算法正在快速兴起,其利用深度神经网络模拟人类大脑神经元的基本功能。

 

 

人工智能市场

显而易见,许多领域将受益于人工智能, 如癌症研究、太空探索、自动驾驶汽车等。 但这些前沿领域面临重重挑战,以致于刚接触人工智能的人认为人工智能无助于这些领域的发展。 但是,人工智能可用于您想不到的一些领域,它是一种应用范围广泛的工具。 借助人工智能,您可扮演游戏中的非玩家角色,实施预测寻路应用,甚至操作牧羊机器人。 人工智能拥有无限可能。

 

人工智能的商业利益

前几年,企业都不愿意投资于人工智能,因为这需要花费大量研究成本。 但这种状况现已改变。 从首席技术官、首席财务官到首席执行官,相关企业高管都深切认识到人工智能解决方案的实用性、甚至必要性。

2014 年,超过 3 亿美元投向了人工智能初创公司,是 2010 年相关投资额(1500 万美元)的 20 倍1。到 2020 年,全球机器人和人工智能市场预计将增长至 1530 亿美元。 仅在医疗领域,人工智能系统的市场规模预计将从 2014 年 6.33 亿美元增长至 2021 年的 60 亿美元以上1;到 2020 年,在所有经济交易中,5% 将采用自主软件进行2。 广大公司正将更多精力投入到人工智能研发和产品设计中,在这方面,您可以做出应有贡献。

 

我应该从哪个领域着手?

人工智能备受关注,且相关机会正在增长。 哪些领域正在使用人工智能? 您可能对游戏并不感兴趣,并希望在学术研究以外的领域实现业务增长。 您还能做什么? 下面列出几个领域以及人工智能在这些领域的增长情况:

医疗行业

  • 图像分析 – 医疗初创公司希望部署可帮助解读 X 射线、MRI、CAT 扫描图等的技术。
  • Dulight* – 这是一种可穿戴设备,可帮助视障者识别食物、金钱等。

汽车

  • 自动驾驶汽车 – 人工智能可帮助自动汽车识别路标、人员及其他车辆。
  • 信息娱乐 – 改进的语音识别可帮助司机更有效地与音乐、地图等工具进行交互。

工业

  • 维修和维护 – 人工智能系统可预测维修需求,改进预防性维护。
  • 精准农业 – 借助高效的施肥方法,人工智能可帮助改进食品生产,加快上市速度。
  • 销售和上市时间 – 人工智能可预测在一年的不同时节,哪些产品将在哪些地区销售的更快或更多,以及在哪些时间为这些产品备足库存或将它们直接发运给顾客更为有利。

体育

  • 性能优化 – 人工智能系统可帮助指导运动员加强锻炼、保持营养均衡以及提高竞技技能。
  • 伤害预防 – 用于设备设计和改进赛中紧急呼叫,甚至预测规则要求,以保障运动员的安全。

从上面的几个例子中,您就能看出人工智能蕴藏着巨大机遇。 人工智能可用于改善生活的方方面面。 改善之道由您决定。

 

 

英特尔助推人工智能发展

英特尔并不仅仅将投资目光放在人工智能增长上,而是致力于推动人工智能革命。 人工智能是英特尔当前的发展要务。为引领这一领域的发展,英特尔将加大研发力度,进行必要收购。 我们基于摩尔定律的产品创新和 CPU 功能集成将继续提供最佳的性能、效率、密度和成本效益。 此外,我们拥有通过开创性技术成功实现技术变革的长久历史,包括内存、显卡、I/O 和无线技术等方面的突破性技术。如今,我们拥有一系列强大工具和独特功能,可帮助实现人工智能变革。

首先,英特尔正采取大胆的新方式缩短人工智能创新周期。 我们收购了全球最出色的深度学习初创公司 Nervana,不仅可加快人工智能数据获取和模型构建的速度,而且明年将通过把 Nervana 技术集成到 CPU 中,大幅提升训练性能,超越 GPU。

其次,随着人工智能广泛用于从数据中心到物联网的各种领域,英特尔可凭借其独特且完整的产品组合提供端到端人工智能解决方案。

最后,在过去从客户端/服务器模式到服务器虚拟化再到云的转型中,英特尔成功发挥了领导作用。

我们可提供关键技术推进人工智能革命,但必须与其他各方紧密合作,发掘人工智能的无限潜力。 为此,英特尔领衔实施了开放的数据交换和计划,努力开发更加易于使用的工具,培训更多行业人才,并推进智能技术的平等使用。 举例来说,在一个开放数据计划中,我们与 Data.gov 建立了良好的合作关系; 我们还与 BMW 开展了开放汽车方面的合作,旨在减少重复工作,加快创新步伐。

英特尔正在开发数据获取和模型构建、训练及部署方面的突破性技术,以缩短更智能、更强大和更具协同性的人工智能代理从概念形成到部署的创新周期。 强大的技术解决方案组合将推动这些人工智能功能早日发挥效用。

 

结论

人工智能正快速革新各行各业,而且日益成为重要的竞争优势来源。 现在是您开始将人工智能融入产品、服务和业务流程的绝佳时机,以保持在您专业领域的领先地位。 访问面向人工智能的英特尔软件开发人员专区: https://software.intel.com/zh-cn/machine-learning,立即行动。

 

  1. Clark, Jack. “重大技术归来: 人工智能的回归”,Bloomberg Technology,2015 年 2 月。 http://www.bloomberg.com/news/articles/2015-02-03/i-ll-be-back-the-return-of-artificial-intelligence
  2. Gartner 新闻稿。 “Gartner 透露了对 2016 年及以后 IT 组织和用户的重要预测”。2015 年 10 月 6 日。 http://gartner.com/newsroom/id/3143718

人工智能领域的开发人员如何起步

$
0
0

至少从 20 世纪 50 年代开始,人工智能的理念就一直吸引着我们,鼓舞着计算机科学家创造越来越复杂的新技术,同时让日常消费者对未来充满期待。 如果我们能够在不冒任何生命风险的情况下探索海洋深处,将会怎样? 如果我们能够乘坐无人驾驶汽车在智能道路上行驶,又会怎样呢? 尽管我们对人工智能及其潜能的理解在过去几十年中发生了变化,但我们有理由相信,人工智能的时代可能已经来临。 那么,作为开发人员,您应该如何起步呢? 本文将讨论人工智能的一些基本知识,并概述一些可能有帮助的工具和资源。 

首先,什么是人工智能?

虽然有很多不同的方式来思考人工智能,并有很多不同的技术来处理,但机器智能的关键在于,它必须能够感知、推断和行动,然后根据经验进行调整。

  • 感知—从大量数据中确定和识别有意义的对象或概念。 这是红绿灯吗? 它是肿瘤还是正常组织?
     
  • 推断—了解更大的背景环境,并制定一个实现目标的计划。 如果目标是避免撞车,汽车必须根据车辆行为、接近度、速度和路况计算撞车的可能性。
     
  • 行动—推荐或直接启动最佳行动方案。 根据车辆和交通分析,汽车可以刹车、加速或准备安全机制。
     
  • 调整—最后,我们必须能够根据经验在每个阶段调整算法,对它们进行重新训练,使他们变得更智能。 自主车辆算法应该进行重新训练,以识别更多盲点,将新变量纳入环境,并根据以前的事件调整行动。

如今的人工智能是什么样子?

如今的人工智能是一个涵盖性术语,代表任何可以感知、推断、行动和调整的程序。 开发人员通过两种方式让机器执行人工智能:机器学习和深度学习。

  • 机器学习中,学习算法从数据构建模型,并随着数据量的增加不断改进。 机器学习有四种主要类型:监督式学习、非监督式学习、半监督式学习和强化学习。 在监督式机器学习中,算法通过处理和分类大量的标记数据来学习识别数据。 在非监督式机器学习中,算法能够以超过人类大脑的速度,快速识别大量未标记数据中的模式和类别。 您可以在本文中了解有关机器学习的更多信息。
     
  • 深度学习是机器学习的一个子集,多层神经网络从大量数据中进行学习。

人工智能的实际应用: 机器学习工作流

正如我们之前讨论的,人工智能能够感知、推断和行动,然后根据经验进行调整。 但它到底是什么样子呢? 这是机器学习的一般工作流:

  1. 数据采集—首先,您需要大量数据。 这些数据可以从任何数量的来源进行收集,包括可穿戴设备的传感器以及其他对象、云和 web。
     
  2. 数据聚合和管理—收集数据后,数据科学家将对数据进行聚合和标记(如果是监督式机器学习)。
     
  3. 模型开发—接下来,数据用于开发模型,然后对其进行精确度训练并针对性能进行优化。
     
  4. 模型部署和评分—模型部署在应用中,用于根据新数据进行预测。
     
  5. 使用新数据更新—随着数据量的增加,模型将变得更加精细和准确。 例如,在自动驾驶汽车的行驶过程中,应用将通过传感器、GPS、360 度视频捕捉等功能提供实时信息,然后使用这些信息来优化未来的预测。

面向人工智能开发人员的机遇

人工智能最令人兴奋的一点在于,它具有无限的潜力,不仅能够变革计算行业或软件行业,而且能够改变与我们的生活息息相关的每个行业。 工业革命、技术革命和数字革命改变了我们生活的方方面面,人工智能将以同样的方式改变整个社会。 英特尔为人工智能提供强大的基础、框架和策略。 涉及深度学习和机器学习技术时,英特尔可帮助开发人员更加经济高效地交付更高质量的项目。

对于开发人员而言,人工智能领域的扩展意味着您可以将自己在人工智能领域的兴趣和知识运用到其他感兴趣的行业中,如音乐、体育或医疗。 当您在探索人工智能的世界时,思考一下自己感兴趣的其他领域,以及如何以有意义的方式为该领域做出贡献。 创意是永无止境的,我们在下面提供了一些例子帮助您思考。
 

那么,我应当从何处入手? 英特尔将助您一臂之力。

英特尔正在鼎力支持人工智能领域的快速创新。 英特尔人工智能软件开发人员专区提供了丰富的入门资源,帮助您快速寻找社区、工具和培训。 下面有一些帮助您入手的链接。

  • 加入人工智能社区– 一个庞大的社区,汇集了世界各地的人工智能开发人员。 通过 Facebook 和 LinkedIn 联系他们,寻找您所在地区举办的各种聚会、研讨会和活动。 英特尔经常参加各种大会,并提供有关人工智能的网络研讨会— 点击此处了解更多信息。
     
  • 您是否是在校学生?了解您的学校是否参与了英特尔® 软件学生开发人员计划。 参加由行业专家、教授和专业人士提供的培训,提升您的技能。 点击此处了解更多信息
     
  • 优化的框架– Caffe* 是最受欢迎的图像识别社区应用之一,Theano* 旨在帮助编写深度学习模型。 两个框架均针对英特尔® 架构进行了优化。 点击此处,了解如何安装和使用这些框架并寻找一些有用的资源库。
     
  • 硬件 - 英特尔® 至强融核™ 处理器产品家族– 这些大型多核处理器为机器学习和深度学习工作负载提供了强大的高度并行性能。 如欲了解使用英特尔® 架构的深度学习,请点击此处。如欲了解英特尔® 至强融核™ 处理器产品家族出色的深度学习性能,请点击此处。人工智能的话题非常深奥,我们目前介绍的只是冰山一角。 请留意我们的更多文章,了解最新动态以及如何参与。      

人工智能的话题非常深奥,我们目前介绍的只是冰山一角。 请留意我们的更多文章,了解最新动态以及如何参与。  

腾讯* 在基于英特尔® 至强® 处理器的游戏内购买推荐系统中使用机器学习

$
0
0

网络游戏现在非常受欢迎,特别是受年轻人的喜爱。 他们在业余时间玩游戏, 在家庭成员或朋友之间玩网络游戏。 在很多情况下,玩家需要通过购买东西为游戏中的人物添置装备,以便赢得其他玩家不具备的优势。

为了增强用户的网络游戏体验,腾讯安装了一款采用机器学习2方法的游戏内购买推荐系统,以帮助用户决定他们想为游戏购买什么装备。

腾讯1是一家互联网公司, 提供数量众多的服务,包括社交网络、web 门户、电子商务和多人在线游戏。

下一部分将介绍推荐系统9、腾讯用于推荐系统的机器学习算法以及英特尔® 至强® 处理器产品家族如何帮助提升该系统的性能。

推荐系统

推荐系统是一种生成推荐物品列表以供用户选择的机制, 用于帮助用户决定购买哪些物品。 推荐系统可用于选择歌曲、电影、研究文章等等。

在腾讯的案例中,其中一款应用就是使用推荐系统为网络游戏推荐合适的装备。

推荐系统使用以下方法生成物品列表:协作方法10、基于内容的方法11或混合方法。

协作方法是基于系统中其他用户的评分或行为进行推荐的算法。 它会分析用户的活动或偏好,并根据他们与其他用户的相似性来预测用户会喜欢什么。

基于内容的算法会根据物品的描述和用户的兴趣资料,向用户推荐一个物品。

混合算法结合了协作算法和基于内容的算法的优势。

腾讯在其游戏内购买推荐系统中使用称为逻辑回归3 的机器学习算法。 下一节将简要讨论逻辑回归及其公式。

逻辑回归

逻辑回归是一种预测分析。 它是用于二进制分类的最流行的机器学习算法之一。 二进制分类意味着结果是二分的,也就是说只有两个类,如赢和输,是和否,真和假,1 和 0。 例如,打赌一匹马将赢得或输掉比赛。 这里我们有两个类,赢和输。 这里的目标/因变量是赌注。 如果这匹马赢得比赛,它的值为 1,如果输掉比赛,则为 0。

逻辑回归就是使用以下等式找出对数几率的概率5

p: 事件存在的概率

1 – p: 事件不存在的概率

β: 权重

x: 自变量

逻辑回归会生成上述公式的系数 β,以预测事件存在的概率。

腾讯游戏内购买推荐系统和英特尔® 至强® 处理器 E5 v4

腾讯机器学习引擎会对大量在线游戏用户的行为进行分析,从而为用户推荐应当在游戏中使用哪些装备。 因此,它需要强大的计算能力来缩短模型训练时间。 它在模块中广泛使用 DGEMM6来计算逻辑回归机器学习算法的系数。 DGEMM 是双精度浮点数的矩阵乘法函数。

腾讯机器学习引擎通过英特尔® 数学核心函数库(英特尔® MKL)利用 DGEMM 函数7。 英特尔至强处理器 E5 v4 产品家族支持英特尔® 高级矢量扩展指令集 2(英特尔® AVX2)8,英特尔 MKL 使用英特尔 AVX2 进行了性能的高度优化。 使用英特尔 MKL 的应用只需链接到最新版本的英特尔 MKL 即可利用未来英特尔® 至强® 处理器中的新功能,因为英特尔 MKL 将自动检测新功能并使用它们(如适用)。

性能测试流程

为了解当前一代英特尔® 至强® 处理器相对于上一代英特尔® 至强® 处理器的性能改进情况,我们在两个平台上进行了测试。 一个系统配备英特尔® 至强® 处理器 E5-2699 v3,另另一个配备英特尔® 至强® 处理器 E5-2699 v4。

测试配置

配备双路英特尔® 至强® 处理器 E5-2699 v4 的系统

  • 系统: 预生产
  • 处理器: 英特尔至强处理器 E5-2699 v4 @2.2GHz
  • 高速缓存: 55 MB
  • 内核: 22
  • 内存: 128 GB DDR4-2133MT/秒

配备双路英特尔至强处理器 E5-2699 v3 的系统

  • 系统: 预生产
  • 处理器: 英特尔至强处理器 E5-2699 v3 @2.3GHz
  • 高速缓存: 45 MB
  • 内核: 18
  • 内存: 128 GB DDR4-2133 MT/秒

操作系统: Red Hat Enterprise Linux* 7.2-kernel 3.10.0-327

软件:

  • GNU* C 编译器套装 4.8.2
  • OpenJDK* 7
  • Spark* 1.5.2
  • 英特尔® MKL 11.3

应用: 腾讯机器学习训练工作负载

测试结果

以下测试结果分别显示了应用级别和系数计算模块的性能改进情况。


图 1: 使用英特尔® 至强® 处理器 E5-2699 v3 的应用与使用英特尔® 至强® 处理器 E5-2699 v4 的应用对比。

图 1 显示了使用英特尔® 至强® 处理器 E5-2699 v3 的应用和使用英特尔® 至强® 处理器 E5-2699 v4 的应用的对比结果。 由于应用是可扩展的,因此它可以调度更多任务在 v4 而非 v3 中并行运行,从而缩短机器学习模型的训练时间。 


图 2:使用启用英特尔® AVX2 的英特尔® 至强® 处理器 E5-2699 v4 时,系数计算模块的性能对比

图 2 显示了在配备英特尔至强处理器 E5-2699 v4 的系统上启用英特尔 AVX2 时,计算系数模块的性能改进情况。 性能提升了 44%。

注:性能测试中使用的软件和工作负载可能仅在英特尔® 微处理器上进行了性能优化。 诸如 SYSmark* 和 MobileMark* 等测试均系基于特定计算机系统、硬件、软件、操作系统及功能。 上述任何要素的变动都有可能导致测试结果的变化。 请参考其他信息及性能测试(包括结合其他产品使用时的运行性能)以对目标产品进行全面评估。 更多信息敬请登录 http://www.intel.cn/content/www/cn/zh/benchmarks/intel-product-performance.html

结论

游戏内购买机器学习推荐系统嵌入在腾讯游戏内。 因此,优化该系统将有助于加速决策流程,让系统为玩腾讯游戏的玩家推荐更好的游戏装备。 英特尔 MKL 使用英特尔 AVX2 来提高在配备英特尔至强处理器的系统上运行应用的性能。

参考资料

  1. 腾讯公司信息
  2. 机器学习
  3. 逻辑回归
  4. 什么是罗吉特
  5. 几率和对数几率
  6. DGEMM
  7. 英特尔® 数学核心函数库
  8. 英特尔® AVX2
  9. 推荐系统的机器学习
  10. 合作推荐
  11. 基于内容的推荐
  12. 混合推荐

分分钟“画”出属于你的物联网应用

$
0
0

在国家“互联网+”战略的大背景下,“物联网”势不可挡的发展前景已经被大家广为认可。可是,当我们真正着手开发一个典型的物联网应用的时候,就会发现事情往往没那么简单。

和传统的应用不太一样的是,物联网应用往往是一个典型的端对端的异构的分布式程序。“端对端”意味着应用涉及到设备端,网关端,还有云端。 “分布式”表示应用的主体功能由部署在多个地方的组件合作完成。而“异构”则表明这些组件长得往往不一样。所以往往为了完成一个小的功能,却需要考虑到这里头的方方面面的技术:网络连接、数据协议、消息响应等等等等 … … 更不要提调试,部署等实施时的具体问题了。

这么多的实际问题都大大提高了物联网开发的门槛以及实现具体应用的效率和质量。今天就和大家分享一个github上的开源项目 – 英特尔® IoT Services Orchestration Layer。在它的帮助之下,开发典型的物联网应用变成了拖拖拽拽“画”个图的事,分分钟就可以搞定,更多的开发者可以更加轻松愉快的“转职”成高产的 “创客”了。

下面就举个例子(类似于Hello World)来介绍一下它的基本功能。

假设我有两个温度传感器和一个电风扇,接在了一块开发板上(例如英特尔® Edison)。想写的应用程序也很简单,如果A传感器测到的温度大于B传感器,就打开风扇,否则就关闭。我们看看怎么不写一行代码,就做出这么个应用。

先把英特尔® IoT Services Orchestration Layer安装到英特尔® Edison开发板之后(具体过程参见项目文档,非常简单,近似于解压),然后我们就可以从电脑用浏览器(例如Chrome)连接上开发板。浏览器会显示一个非常酷炫的HTML5的开发者界面,里面有设置好(如何设置参见项目文档)的各种服务,例如测量A传感器温度,测量B传感器温度,开关电风扇等。

然后,写程序的过程就变成了拖拽这些服务,根据它们之间数据的传送关系连线,“画”出一个或者多个“工作流”的过程。对这个应用而言,“工作流”相当简单,如下图所示,就不具体解释了。

“画”好了程序逻辑之后,我们还可以接着“画”程序的界面。如下图,里面有一堆预设的控件,我们可以拖拽希望使用的控件进行布局——这里为了演示,我一下子使用了8个控件。

为了让这些控件正确显示或者发送数据,我们需要回到刚刚完成的工作流当中接着“画”——要把那8个控件也加进来。例如把测量A传感器的服务和一个仪表盘连一个线,表示测到的温度要由这个仪表盘控件显示。

那么现在,我们的物联网应用就开发完成,大功告成了。直接点击按钮启动程序,下图是看到的结果,一个是实物,我们用手摸一摸A传感器,它测到的温度就会比较高,然后风扇就启动了。同时我们也可以用浏览器看到应用的界面,里面按照我们刚刚“画”的方式,显示了温度,风扇状态等各种信息。

有时候开发完成之后,我们想把这个应用分享给别人,让他们可以在自己的环境中直接下载使用我们开发的程序。这个过程也非常便捷,如下图所示,可以点击分享按钮把自己的应用发布到云端的应用仓库。别的开发者就可以在他们的开发界面中点“安装”来搜索,下载和部署这些发布在应用仓库里程序。

整个过程是不是很简单?项目的地址是https://github.com/01org/intel-iot-services-orchestration-layer。项目是基于Node.js开发的,所以也发布在npm(Node.js Package Manager)上,名字是iot-sol。 里面带丰富文档,和各种示例。

最后,作为一个开源项目,除了作为它的使用者,把玩之余,你还可以为它的不断发展做出贡献:推广,报bug,提出建议,增加内置的服务,扩展功能等。赶快去下载试试吧!

作者简介:

丁俊勇

首席架构师,英特尔亚太研发有限公司Web技术和优化中心;
英特尔首席工程师,专注于JavaScript,IoT,编译器,HTML5,性能优化等领域。

 

另辟蹊径 - 利用WebGL2Native对WebGL程序进行性能调优

$
0
0

WebGL作为HTML5里面一项重要的技术,能够让Web开发者开发精彩的3D游戏和应用,已经在Web Client端得到了广泛的应用,例如著名的Google Maps, 基于WebGL的游戏引擎Unity。由于WebGL程序一般带有复杂的渲染逻辑,那么烦恼也随之而来,即如何对这些WebGL程序包括浏览器本身的实现进行Debug和性能调优成为Web和浏览器开发者的一项重要工作。

我们在浏览器开发工作中发现对WebGL程序进行调试的工具很少,已知的只有针对Chrome的插件WebGL Inspector,能够进行简单的功能性的调试,比如调试每一步的渲染是否正确。然而对于一个遇到性能瓶颈的WebGL程序,想要弄清楚是程序本身的问题还是浏览器本身的实现不够优秀,WebGL Inspector几乎帮不上忙。为了帮助我们解决此类问题,尤其当相关的WebGL应用很多的时候,我们另辟蹊径,开发了一种名叫WebGL2Native的工具。WebGL2Native能够把WebGL的程序转换为基于OpenGL ES 2.0的本地应用程序。有了这个本地应用程序,我们可以:1. 利用现在的成熟的OpenGL性能调试工具如Intel的GPA,Qualcomm的Adreno GPU Profiler等来进行调试。2. 由于转换出来的代码排除掉了浏览器本身的实现,只包含WebGL程序的代码,我们可以通过对比本地应用和浏览器的WebGL应用,快速地确定造成问题的原因是来自WebGL代码本身还是浏览器的内部实现。如果果真是WebGL代码有问题,那么我们可以对本地应用利用成熟的图形工具套件进一步分析找到造成问题的根本原因。

下面是WebGL2Native的框架示意图。 WebGL程序运行在Host上,所有的Http/Https请求发送给Proxy服务器,Proxy服务器拿到请求的资源后通过修改Response注入JavaScript代码并发送给Host上面的WebGL程序。注入的JavaScript代码将负责收集WebGL运行的所有命令和参数并最终发送给Proxy服务器,由Proxy服务器进行转换成基于OpenGL ES 2.0的本地代码,最后打包成本地应用。在Android平台上,那就是一个应用程序安装包。

通过WebGL2Native这个工具,我们曲线实现了对WebGL程序的问题分析,比如性能调试,并在我们的工作中解决了一些实际问题:比如发现了Chrome浏览器对WebGL应用抗锯齿效果的实现在不同平台不尽相同,我们顺势针对某些特定平台利用平台特性进行了特异的优化,极大的提高了其抗锯齿效果在特定平台上的性能。

作者简介:

杨进

英特尔亚太研发有限公司Web技术和优化中心软件工程师,
专注于浏览器渲染方面的性能分析和优化。

 

直播新模式:点评式互动直播

$
0
0

互动直播已经成为直播行业发展的下一个技术热点。当前的互动直播大多是指主播与某一个观众双向视频互动(连麦),或者主播和多个观众之间交流。现在还出现了一种崭新的直播模式——点评式互动直播。

点评式互动直播是指主播本身不参与互动,但是某些观众之间可以互动评论,并且该互动过程与主播的视频流可以一同直播给所有观众的直播模式,为各种个性化私密直播提供了可能。

人气主播作为一个稀缺的资源,除了传统方式的CDN推流,或观众参与到实时视频互动以外,还可以以其他方式发挥这个资源的价值,譬如,定制开通很多点评式互动直播的房间,观众可以自由组合加入到房间,观众在享受主播的精彩表演,还可以在观众之间实时互动,形成精彩点评,并将这个互动的过程形成新的IP,推送到其他感兴趣的观众,产生新的商业机会。这种场景,在观看球赛、电子竞技节目、娱乐综艺、热门电视剧、电影等也同样合适。这种方式是对弹幕这种实时文字点评的新的发展。

但是点评式互动直播的技术实现难点重重。相较于传统直播,点评式互动直播的技术挑战在于:

  • 高质量、广泛连通性的实时流汇聚的基础架构

传统的直播大多都是单路流进入CDN,由CDN分发出来传递给观众。流拓扑是个单向广播的结构。而点评式互动直播中,增加了多路评论员的流,且需要把主播的直播流和评论员的流都推向观众。在这个过程中,常规做法是将所有的流分别单独推向观众。这对观众的终端的接收带宽和媒体处理能力形成很大压力,终端的适配性差。更好的做法是在云端就将所有的媒体流整理汇聚,再在自动适配终端的类别,只推送一路媒体流进入终端。这种复杂处理,需要云端的媒体处理架构具有强大的实时流汇聚的能力。

  • 即时的直播间创建和资源配置

在点评式互动直播的模式下,可以预计同一个人气主播或者热门节目,会有多个直播间被随机创建,直播间大小不一,存续时间也各不相同。这对支持直播间资源的调配提出很高的要求。直播间需要被实时的创建,直播间关闭时,资源需要实时的回收。在直播的业务量到达系统承受上限的时候,系统需要在不影响现有业务的前提下,迅速无缝地扩展系统资源。因而灵活的资源配置策略是点评式互动直播的必要条件。

  • 提供给观众灵活的参与通道

点评式互动直播的显著特点是观众对直播的参与感大大增强,因而系统需要提供机制让普通观众可以随时升级为评论员的角色参与讨论,相应评论员也可以随时变为普通观众角色。这个需要系统提供观众在CDN通路和MCU通路灵活切换,这需要解决延时性、权限管理、接入信令控制等重要问题。

好消息是“面向WebRTC的英特尔®协同通信开发套件”已成功解决上述直播技术难点,可以用来轻易实现多种互动直播模式。并且该开发套件完全免费对外开放,欲了解更多详情请访问webrtc.intel.com

作者简介:

段先德

英特尔亚太研发有限公司Web技术和优化中心软件架构师;
从事电信领域的软件设计开发十余年,致力于面向大规模并发的可靠的分布式实时通信系统的架构设计与开发,用软件技术化解实时通信系统的核心复杂性。

 

谈HTML5之- Web多线程利器WebWorker介绍

$
0
0

内容提要:

  • 什么是WebWorkers
  • 为什么要有WebWorkers
  • WebWorkers的能力
  • 怎么使用WebWorkers
    • Dedicated Worker
    • Shared Worker
  • 开发者工具支持
  • 展望

正文:

Web Workers[1]是W3C和WHATWG定义的Web多线程标准, 是HTML5平台的重要组成部分。使用Web Workers API,HTML5程序员可以构建多线程化的应用,对于提升原有应用的性能,改善用户体验有非常重要的意义。应用级的多线程接口在Android,iOS,Windows,QT等平台上都是非常重要的一部分,从这个意义上看,Web Workers也是HTML5平台化的重要一环。

Web Workers在W3C的演进,在2012年5月已经到了Candidate Recommendation阶段,得到主流浏览器的广泛支持,详见这里

为什么要有Web Workers?在笔者看来,主要有几个原因:

  1. 这是个多核的世界。服务器端自不用说,从个人电脑,到手机平板,多核心已经是主流。Web上提供多线程编程接口,才能通过在应用层对任务细分,充分利用硬件的能力。
  2. Web / JavaScript本身是单线程的。JavaScript本身只提供单线程的执行环境,没有多线程的语义。Web从出生开始,也默认很多工作都要在一个UI线程中完成,这包括页面解析,DOM的操作,CSS的计算,布局,页面渲染等业务逻辑,UI线程非常繁忙,导致性能差,不流畅。随着浏览器的演进,在引擎层面上,Web 引擎提供了多线程的页面解析,多线程渲染加速,Javascript引擎也提供了多线程编译,多线程垃圾回收等机制,这些将一部分业务从UI线程中剥离,通过并行来加速。在应用层面上,也提供异步的编程接口,例如异步xmlhttprequest, 以及setTimeout, setInterval等接口,尽可能的使UI线程不被阻塞。但这些还是不够,随着HTML5应用越来越复杂,出现越来越多的将应用的业务逻辑也多线程化的需求。例如:
    1. )在worker线程对用户的输入做拼写检查,从而不影响UI线程的响应性。
    2. )将任务分配到多个线程中,并行计算,加速渲染,例如分形算法。
    3. )分析audio或者video数据等密集计算。
    4. )本地的Web database的更新。
    5. )应用的资源预取和缓存。

Web Workers API定义了两种worker,一种是Dedicated Worker, 另外一种是Shared Worker。Dedicated Worker只能在他被创建的Context中访问。而Shared Worker一经创建,可以在同一个域里面的多个Context共享访问,例如不同的frame,不同的page。

Web Workers的能力

原则上,worker不具备任何直接影响页面的能力,例如DOM操作。而是需要通过postMessage通知UI线程,间接的影响页面。这种设计的思想和主流的多线程UI设计思想也是一致的。Worker具备的能力:

  • navigator对象
  • XMLHttpRequest
  • setTimeout()/clearTimeout() and setInterval()/clearInterval()
  • importScripts()
  • performance对象

Worker不具备的能力:

  • DOM
  • window对象
  • document对象

通过Chrome开发者工具,可以查看Worker具备哪些能力。

接下来将介绍这两种worker的主要API。

  Dedicated Worker

如何创建一个Dedicated Worker

var worker = new Worker(“workerScript.js”);

上述语句会启动一个新的线程,下载workerScript.js并执行,注意,此处将是一个全新的执行环境,和创建worker的环境完全独立。

如何和一个Dedicated Worker通信

在UI线程向worker发送消息:

worker.postMessage(any message, optional sequence<Transferable> transfer);

这里会将message对象发送给worker线程,如果第二个参数transfer为空,message对象将会被序列化,而后传递到worker线程,worker线程反序列化,构造出message对象。这个过程是完全的拷贝。

第二个参数transfer用来指明哪些要避免拷贝,而是要transfer所有权到另外一个线程。以transfer列表包含Transferrable Object obj为例,这意味着message中的obj要transfer到worker线程;那么postMessage之后,UI线程的JavaScript执行环境将不再拥有obj,而Worker线程会拥有obj,这类似C++ STL里面的auto_ptr。ArrayBuffer是一种常见的可传递对象,可以支持大数据在线程之间传递,从而避免了拷贝。目前所支持的Transferrable Object见这里

关于transfer列表,除了以上之外,2015年刚刚开始提案的新标准SharedArrayBuffer里面定义的SharedArrayBuffer这个类型,可以在多个线程之间共享,这类似于C++ STL里面的shared_ptr。

在worker线程接收消息:

  onmessage = function(message) {

    …

}

在workerScript.js里实现onmessage函数,这里用来接收从主线程发过来的消息。

如何从Dedicated Worker线程发送消息到UI线程

在worker的执行环境里

postMessage(any message, optional sequence<Transferable> transfer);

语义同从UI线程向worker线程传递消息。

在UI线程里接收消息

worker.onmessage = function (message) {

  …

}

注册onmessage回调函数到worker对象,可以接收worker线程传递过来的消息。

如何停止worker线程的执行

如果在UI线程停止worker运行

worker.terminate();

worker线程在隐式地收到terminate消息后,消息队列里的未处理的消息会被丢掉,不再被onmessage函数处理。

如果在worker线程停止运行,则可以调用方法:

close();

close被调用后,所有已经在worker线程的消息队列里的消息都会被丢掉,不再被onmessage处理。

错误处理

worker.onerror = function(error) {

  …

}

在UI线程,注册onerror回调函数到worker对象,那么worker线程在有runtime error发生的时候,会发error事件给主线程。

示例

下面是一个简单的例子,用来描述Dedicated Worker的使用。主线程创建worker线程,worker用来计算素数,并且返回给UI线程做显示。

  Shared Worker

如何创建一个Shared Worker

  var worker = new SharedWorker(“service.js”);

上述语义,在同一个origin范围内,如果尚未存在以service.js创建的shared worker,则会创建新的线程,下载service.js,在一个新的执行环境中运行,并且在UI线程返回SharedWorker对象,这个对象会带一个MessagePort[2],用于和shared worker通信。

如果已经有以service.js创建的shared worker,则不再创建新的线程,而是在UI线程返回一个SharedWorker对象,可以和shared worker通信。此处是以SharedWorker构造函数的参数作为区分,不同的URL创建不同的shared worker线程,相同则共享同一个shared worker。另外,SharedWorker只能在与它相同的origin的执行环境中被访问。

UI 线程如何向Shared Worker发消息

  SharedWorker构造函数返回的对象会带一个MessagePort,用来和worker通信。

首先,建立和SharedWorker的连接,在 UI 线程上worker的onmessage函数注册,或者显示的调用MessagePort的start方法。

  worker.port.onmessage = function cb(…) { }

  或者

  worker.port.addEventListener(function cb(…){ });

  worker.port.start();

  这样,SharedWorker线程的onconnect回调函数会被调用,这个回调函数的参数中可以拿到对应UI线程对应的MessagePort,然后再在这个port上注册onmessage回调函数,就准备好从UI 线程上接收消息了。例如:

  onconnect = function(e) {

    var port = e.ports[0];

    port.onmessage = function()…

}

再然后,UI线程上可以用postMessage方法向SharedWorker发消息,这里和Dedicated Worker的语义是一样的,不同的是,Transferable Object在Shared Worker里并不一定被支持。

Shared Worker如何向UI 线程发消息

  接上,在SharedWorker在onconnect的回调函数里拿到MessagePort之后,就可以通过这个port和对应的UI线程里的对象通信了。

  port.postMessage(…);

如何停止Shared Worker线程的执行

Shared Worker线程可以通过调用close方法停止worker。

和Dedicated Worker有所不同,UI线程里的shared worker对象并没有terminate方法。

错误处理

  同Dedicated worker

示例

这个示例演示了Shared worker和UI线程连接之后,shared worker会向UI线程发送‘Hello World‘消息。

开发者工具支持

Dedicated Worker由于总是和创建它的执行环境关联,所以在页面调试的Source面板同样可以进行worker调试。如下图,选择要调试的线程,并且给该线程的JavaScript代码添加断点。例如:

而对于Shared Worker的调试,则要在独立的调试环境下,具体步骤如下:

  1. Chrome地址栏输入chrome://inspect并回车。
  2. 在inspect页面左侧列表选中Shared Workers,然后点击inspect链接

  3. 然后会跳出新的Chrome开发者工具窗口,可以进行shared worker调试。如下图所示:
     

展望

W3C Web Workers标准,在应用层面线程化,利用硬件的多核能力提高性能,改善用户体验起到非常重要的作用。但由于JavaScript语言天然地缺乏线程语义,编程接口也只能设计为消息传递,而非变量共享。随着HTML5的发展,有越来越多的场景需要在UI线程以及多个worker线程之间共享数据,为此,业界也开始提出新的标准提案SharedArrayBuffer[3],在这个新提案中不仅增加了共享的数据类型,而且在此之上定义了原子操作的语义和线程同步的语义,进一步缩小了HTML5平台和传统原生应用在多线程能力上的差距。

 

更多相关内容,请参考

[1] https://www.w3.org/TR/workers/
[2] https://www.w3.org/TR/2011/WD-webmessaging-20110317/#message-ports
[3] https://tc39.github.io/ecmascript_sharedmem/shmem.html

 

作者简介:

邓攀

资深码农,英特尔亚太研发有限公司Web技术和优化中心,长期耕耘于Web领地

 


基于同步通知机制的Chrome浏览器在Android系统上的内存优化

$
0
0

作为目前最受欢迎的一款浏览器,Chrome给用户带来了丰富的功能和体验。与此同时,Chrome常常因为内存使用不当而成为大家关注的焦点。尤其在内存配置较少的Android设备上,系统由于内存被Chrome大量占用,常常会引起性能的降低,甚至最终导致应用程序的崩溃。

作为移动操作系统,Android系统自己其实有一套行之有效的内存管理机制,或者说有两种机制驱动共同起作用。首先是内核(kernel)驱动的LMK(Low Memory Killer)机制,这部分是由Linux内核的Out-Of-Memory(OOM)Killer机制演变而来。其机制简单来说就是当内存紧张时,Android 内核会根据一定的判断条件,根据进程优先级杀死低优先级进程,达到强制回收内存的目的;另一套是Android 框架(Framework)驱动的内存管理机制。为了避免进程最终被强制杀死而影响用户体验,Android框架允许进程注册相关的内存通知接口(ComponentCallbacks2 API),接收来自框架的内存使用情况的通知。通常情况下,Android 框架针对不同的进程把内存紧张程度分成7个等级,这样进程就根据当前系统内存紧张程度和自己所处的优先级,提前主动释放一些不必要的内存,从而延迟或避免内存被系统强制回收。

做为运行在Android设备上一个复杂应用,Chrome浏览器在Android系统的内存管理机制上,做了自己的对接和扩展。首先是Chrome中专门有一个线程利用MemoryPressureListener类来分发内存通知,通过异步的方式,把来自Android框架的内存使用情况分发通知到相关模块,比如2D渲染引擎Skia、布局(layout)引擎Blink以及JavaScript引擎V8等等。每个模块在收到通知后会主动提前释放一些不必要的内存。其次,尽管Chrome浏览器能同时打开多个网页,但任何时候用户总使用其中某一个页面。这样Chrome根据一定的策略把某些长时间不用的页面暂时挂起,尽量释放不必要的内存;而当用户切换到被挂起页面时,再按需要分配内存重新初始化。

尽管如此,由于Android框架的内存使用情况是用异步方式通知的,这样就无法保证在内存紧张的时候,进程有足够多的时间来传递通知和主动释放不必要的内存。因此当进程或者相关模块忙于执行其他任务时,他们就不能及时响应内存通知和优化内存占用,最终导致内存被强制回收和进程被杀死。我们在实际工作中就发现了这样的问题,我们调查了40个常用网站(见图1),发现15% (6个)的网站内存通知延误响应的现象比较严重(>0.5秒),在某些严重延误的情况下(见图2),可以看到由于内存通知响应甚至被JavaScript计算给延误了2.5秒,最终导致了Android设备上Chrome浏览器的崩溃。针对这个暴露出来的问题,我们对某些延误比较严重的模块,增加了同步通知的接口MemoryPressureListener::SyncNotify,让来自Android框架的紧急内存通知得到及时的响应,从而有效的减少了进程内存使用。在我们的测试中,当打开某些复杂网站时,Chrome浏览器崩溃的概率从优化前的50%降低了到了优化后的20%,优化幅度竟达50%以上。

 

Sample time series carbon monoxide sensor plot
图 1. 常见网站的内存消息响应延迟

Sample time series carbon monoxide sensor plot
图 2. 内存消息响应延迟的典型表现

 

作者简介:

郑宏

英特尔亚太研发有限公司Web技术及优化中心软件工程师;
长期从事浏览器的性能分析和优化工作,主要领域包括page loading和memory

 

 

 

 

 

韩骏超

现就任于英特尔亚太研发有限公司Web技术和优化中心软件工程师;
专注于浏览器渲染方面的性能分析和优化。

 

使用AVX2指令集加速Chrome浏览器的图像操作

$
0
0

指令集是CPU中用来计算和控制计算机系统的一套指令集合,也是软件与CPU硬件这两个层级之间的规范和接口:任何软件最终总要翻译成一条条指令才能让CPU硬件识别并执行,而CPU硬件则依靠指令来计算和控制系统。所以指令集功能的强弱和执行的效率是衡量CPU性能的重要指标,指令集的设计和使用自然就是提高CPU效率的重要环节。

正因为其无可替代的重要作用,每一款新型的CPU在设计时自然会精心挑选一系列与其硬件电路相配合的指令集。比如,英特尔1996年在其Pentium CPU架构设计中率先引入SIMD(Single Instruction Multiple Data,单指令多数据)指令集设计思想,添加了MMX(Multi Media eXtensions)多媒体扩展指令集,使其CPU能在一个时钟周期内用一条指令可以完成多个数据的操作,从而大大提高了CPU处理多媒体应用的效率。在一代代英特尔CPU架构的演进下,英特尔在2008年进一步公布了AVX指令集规范,并在Sandy Bridge CPU架构中将首先实现了全新的AVX指令集,把浮点矢量宽度从MMX时代的64位拓宽到了256位,最直接的收益就是浮点性能最大提升了4倍,并且在最新的AVX2中把整数的矢量宽度也同步增加到256位。

理论总可以描绘得很美好,但能不能应用到日常软件,为最终用户带来性能和体验的提升,这才是大家最为关注的。我们这里就举一个在我们实际工作中的例子,看AVX2是如何帮助大家常用的Chrome浏览器带来网页浏览上的性能提升。随着手机和电脑屏幕分辨率的不断提升,屏幕显示的分辨率往往会大于网页中图像的原始分辨率。此时Chrome浏览器就需要对图像进行放大。Chrome使用二维图形引擎Skia,运用Mitchell滤波器进行高质量的图像放大处理,而图像放大过程就是将图像与滤波器进行卷积操作(像素与滤波器系数相乘相加)的过程。由于图像一般表示为RGBA四个通道,每个通道存储0-255八位颜色值,因此最基本的方法是循环对每个像素的每个通道逐一运算(图1),但这样并不高效;而这样的操作其实很适合用AVX2指令集进行加速,因为AVX2可以一次处理256位数据,也就是8个像素,并且同时对RGBA四个通道进行运算(图2)。这样就可以大大提高运算效率,大幅获得速度提升。

Sample time series carbon monoxide sensor plot
图 1


图 2

当然实际应用中需要考虑更多因素,而且整个二维图像滤波需要水平方向和垂直方向两次运算才能完成,因此算法的具体实现会比我们描述的稍微复杂一些。首先是位扩展和转换,我们一次读取8个像素也就是32个8位颜色值,但滤波器的系数是用16位的定点数表示的。我们需要先将8位颜色值扩展为16位,接着同时对16个16位整数进行乘法等操作,再把结果重新转换为8位颜色值存储并对溢出情况进行特殊处理。此外,还需对图像边缘(剩余不被8整除的像素)等情况进行特殊处理。但总的来说,我们的优化算法还是获得了可观的回报,在实际场景中,使用AVX2的算法相比原先SSE2的算法,可以达到近一倍的速度提升。

 

作者简介:

张相泽

英特尔亚太研发有限公司Web技术和优化中心软件工程师,
热衷于Web技术,主要进行浏览器图形渲染方面的工作。

 

 

 

 

 

杨进

英特尔亚太研发有限公司Web技术和优化中心软件工程师,
专注于浏览器渲染方面的性能分析和优化。

 

对比英特尔® Joule™ 模块和英特尔® Edison 模块

$
0
0

概述

英特尔® Joule™ 模块是强大的英特尔多功能开发板系列中的最新产品,包含一个英特尔® 凌动™ 四核处理器(时钟速度高达 1.7 GHz)、4 GB LPDDR4 RAM、双频带 Wi-Fi 天线、蓝牙® 和一个英特尔® 高清图形处理单元。这些配置使英特尔 Joule 模块的功能比前代开发板的功能更强大。这款新型处理器实现了其前代产品 - 英特尔® Edison 平台和英特尔® Galileo 平台不具备的功能,如高级计算机视觉功能和机器学习功能。

为了更好地了解英特尔 Joule 模块,对英特尔 Joule 模块和英特尔® Edison 模块进行对比。首先进行硬件快速比较,然后进行软件比较和尺寸比较,最后进行可用性评估。

 


 

硬件

快速比较

英特尔® Joule™ 模块

英特尔® Edison 模块

1.5 或 1.7 GHz 英特尔® 凌动 处理器

500 MHz 英特尔® 凌动™ 处理器

3 或 4 GB LPDDR4 RAM

1 GB DDR3 RAM

8 或 16 GB eMMC 闪存

4 GB eMMC 闪存

802.11ac Wi-Fi,支持 MIMO

双频带 5.0 GHz 和 2.4 Ghz Wi-Fi

蓝牙®

蓝牙®

英特尔® 高清  图形处理单元

无图形处理单元

 

由上表可以看出,英特尔 Joule 模块在有限的体积内集成了极为强大的处理器,包含一个四核处理器,支持 4 个可用执行线程。相比之下,英特尔 Edison 模块采用双核英特尔凌动处理器,时钟速度为 500 MHz。这意味着英特尔 Joule 模块利用不到三分之一的处理速度获取了一半的执行线程。在既定时间内能够处理更多输入数据。例如,英特尔 Edison 平台需要将若干传感器收集的数据转发到网关或台式机,才能正确处理数据。相比之下,英特尔 Joule 模块能够快速处理数据,并将产生的信息发送到任何设备。

此外,英特尔 Joule 模块的显卡处理器能够处理主板上的视频和图像,收集视频和图像的信息以备他用,但是英特尔 Edison 模块不具备这些功能。英特尔 Joule 模块提供了图形化用户界面,提升整个系统的易用性和速度。

在内存方面,英特尔 Edison 模块仅配备 1 GB DDR3 RAM 和 4 GB eMMC 闪存,安装操作系统后内存大约只有 2 GB。这减少了设备能够安装的应用,限制了程序运行时的可用内存。英特尔 Joule 模块配有高达 8 GB 或 16 GB eMMC 闪存(闪存大小取决于您的需求)和 4 GB LPDDR4 RAM。内存的扩大意味着单个英特尔 Joule 模块可同时处理多个应用。

通过上述对比可以得出,与英特尔 Edison 模块相比,英特尔 Joule 模块能处理更大型的工作负载,也能同时处理若干小型工作负载,即使是图形处理线程。总而言之,英特尔 Joule 模块比英特尔 Edison 模块功能更强大,可以在较短时间内处理更多信息,还能处理图形。

 


软件

由于两者开发环境相似,且都支持英特尔® XDK 和英特尔® System Studio IoT Edition,英特尔® Joule™ 平台英特尔® Edison 平台之间的软件差异较小。英特尔 Edison 平台采用一种名为 Poky* 的 Linux* 版本,为设备提供仅限终端的接口。因此,用户只能选择 Linux* 终端。

相比之下,英特尔 Joule 平台配有面向物联网的参考 Linux*。该 Linux* 版本是一个独特的平台,更加接近“经典” Linux* 发行版。和 Linux* Mint 及 Ubuntu* 类似,它提供一种 root 访问终端,通过 HDMI* 或一系列端口(如 PuTTY)进行输出。您可以通过该终端连接主板,随意执行任意 Linux 命令。

该 Linux* 版本配有经典桌面和简单易用的 X 界面形式,为 Linux* 新手提供了更简单的入门级图形界面。该模式仍需与终端进行交互,但已将交互降到了最低。

 



外形尺寸

英特尔 Edison 计算模块尺寸仅有 35.5 x 25 毫米,厚度为 2.9 毫米。尺寸极小,便于用于多种移动应用,随时随地发挥作用。

英特尔 Joule 模块尺寸为 48 x 24 毫米,厚度为 3.5 毫米,其体积比英特尔 Edison 模块增加了大约 600 立方毫米,确保在温度调节、电源管理、Wi-Fi 和 蓝牙® 方面实现较高性能。虽然英特尔 Joule 计算模块体积较大,不适合“可穿戴”应用,但是携带了非常实用的额外电源。

 



可用性

英特尔 Edison 平台是一种相对成熟的实用工具。虽然许多人已经适应了英特尔 Edison 平台,但是,达到较高的适应程度需要花费一定的时间和精力进行学习。用户刚开始学习 Linux* 终端时,会很快陷入困难。尽管为了提高英特尔 Edison 平台的易用性,专门开发了各种工具,但是完全掌握该平台仍需具备相当的 Linux* 知识。

英特尔 Joule 平台通过提供更多选择(如前面提到的 X 界面)简化了使用方法,克服了这个困难。参考 Linux* 发行版配有易于使用的图形界面,用户可以通过该发行版迅速掌握 Joule 模块,降低了学习难度。操作系统仍提供经典终端访问,以供熟练掌握英特尔 Edison 平台的用户使用。这使得英特尔 Joule 平台比英特尔 Edison 平台更易于掌握。此外,今年晚些时候将推出面向 Windows® 10 IoT Core* 和 Ubuntu Core (Snappy)* 的支持。

 



英特尔® Joule™ 平台的应用范围

英特尔 Joule 平台与英特尔 Edison 模块体积相似,前者提供更强大的功能,但是您可能会问:“我能用英特尔 Joule 平台做什么?”答案是,它几乎可以帮您完成所有的任务。借助英特尔 Joule 平台,您可以开发更快速、更出色的可穿戴技术,将其嵌入制造系统,建造无人机,或者开发面部识别应用。它的应用范围是无限的。

截止到撰写本文时,我个人使用该平台长达两个月之久,英特尔 Joule 开发平台具备强大的功能,我能够充分发挥我的创意,将其用于各种不同的领域。我相信该设备将吸引广大用户,实现更多的突破,并对此充满期待!

英特尔 Edison 平台和前代英特尔 Galileo 平台证明了人们能够不断突破技术的上限,英特尔 Joule 模块也将继续超越技术的高峰。一想到人们将利用这个全新设备实现技术进步,我就激动不已,相信它能大大超越前代设备。

 

您将如何使用英特尔 Joule 平台?

如欲获取相关入门信息,请查看专门针对英特尔® Joule 模块编写的代码示例

访问 Github

BigDL:一种面向 Apache Spark 的分布式深度学习库

$
0
0

什么是 BigDL?

BigDL 是一种面向 Apache Spark* 的分布式深度学习库, 用户可以通过 BigDL 将深度学习应用编写为标准的 Spark 程序,这些程序可以直接在 Spark 或 Hadoop 集群上运行。

BigDL

  • 丰富的深度学习支持。 BigDL 模仿Torch,为深度学习提供综合支持,包括数值计算(借助Tensor)和高级神经网络;此外,用户可以利用 BigDL 将预训练CaffeTorch模型加载至 Spark 程序。
  • 极高的性能。为了获得出色的性能,BigDL 将英特尔 MKL和多线程编程应用到每个 Spark 任务中。 因此,相比现成的开源CaffeTorchTensorFlow,BigDL 在单节点至强处理器上的运行速度高出多个数量级(即与主流 GPU 相当)。
  • 高效的横向扩展。 BigDL 通过Apache Spark(一种极速分布式数据处理框架)实现高效横向扩展,执行“大数据规模”数据分析,在 Spark 上有效实施同步 SGD 和 all-reduce 通信。

 

 

为什么选择 BigDL?

如果在编写深度学习程序时面临如下情况,建议使用 BigDL:

  • 在存储数据的大数据 (Hadoop/Spark) 集群(如 HDFS、HBase、Hive 等集群)中分析大量数据。
  • 在大数据 (Spark) 程序和/或工作流程中添加深度学习功能(训练或预测)。
  • 利用现有的 Hadoop/Spark 集群运行深度学习应用,随后与其他工作负载动态共享(例如 ETL、数据仓库、特性设计、经典机器学习、图形分析等等)。

BigDL Program Flow Chart

 

 

如何使用 BigDL?

浏览全部文档

从 Github* 中获取 BigDL

 

 

支持

人工智能 —— 计算领域的下一场重大革命

英特尔® 实感™ SDK 互联网组件卸载指导

$
0
0

英特尔已决定停止市场推广和开发英特尔® 实感™ 互联网组件及相关的样本和应用程序。 其他组件,特别是英特尔® 实感™ SDK 版本 2016-R2 和 2016-R3,不受此决策的影响。

由于此应用程序在其依赖项之一中包含一个安全漏洞,因此建议所有客户从其系统中移除这些组件。

英特尔 PSIRT 发布了安全通报 INTEL-SA-00066(见于 www.intel.com/security),内含对所涉系统的影响的详情,并宣布不再支持英特尔® 实感™ 互联网组件。

此通告及相关行动自 2017 年 2 月 1日起生效。

适用于 Windows® 10 的移除指导:

  1. 用 Microsoft Windows 的“设置”或“搜索”导航到“系统 -> 应用和功能”
  2. 移除两个组件
    1. 英特尔(R) Technology Access
    2. 英特尔® 实感™ SDK Web Runtime

适用于 Windows® 7 的移除指导:

  1. 前往 Windows“开始”菜单 -> “控制面板” -> “程序和功能”
  2. 从安装的程序列表中移除两个组件
    1. 英特尔® 实感™ SDK Web Runtime
    2. 英特尔(R) Technology Access

在英特尔® 至强融核™ 协处理器上微调矢量化和内存流量:对小型矩阵进行 LU 分解

$
0
0

作者:Andrey Vladimirov(Colfax International)

之前已经讨论了有关微调基于英特尔® 至强融核™ 协处理器应用的自动矢量化循环性能的常用技术,这些技术包括强度折减、调整矢量化模式、数据对齐、对齐数据提示和指示器消歧。还展示了内存流量调优的循环分块技术。以下示例阐述了优化方法,该示例对 128×128 尺寸的单精度矩阵进行单线程 LU 分解。

性能指标评测显示,优化后的协处理器性能比未经优化的代码提升了 2.8 倍,多核主机系统的性能提升了 1.7 倍,主机和协处理器的性能大致相同。

可以通过以下链接免费下载文中涉及的代码 https://github.com/ColfaxResearch/LU-decomposition


面向英特尔® 至强融核™ 处理器的 Offload over Fabric教程

$
0
0

英特尔® C++ 编译器支持的 OpenMP* 4.0 设备构造可以通过外设组件接口 Express*(PCIe*)将工作负载从基于英特尔® 至强® 处理器的主机卸载至英特尔® 至强融核™ 协处理器。Offload over Fabric (OoF) 可以扩展这个卸载编程模型,以支持第二代 英特尔® 至强融核™ 处理器,也就是说,基于英特尔® 至强® 处理器的主机可以通过 OoF、利用高速网络(如英特尔® Omni-Path 架构 (Intel® OPA) 或 Mellanox InfiniBand*)将工作负载卸载至第二代至强融核处理器。

本教程展示了如何安装 Oof 软件、配置硬件、测试基本配置和启动 Oof。本教程提供示例源代码,以展示 Oof 的工作原理。

硬件安装

本教程中使用了两台设备:作为主机的英特尔® 至强® 处理器 E5-2670 2.6 GHz 处理器和作为目标设备的英特尔® 至强融核™ 处理器。主机和目标设备运行 Red Hat Enterprise Linux* 7.2,都配有千兆位以太网适配器,以支持远程登录。需要指出的是,主机和目标设备的名称分别为 host-deviceknl-sb2

首先,我们需要设置高速网络。由于硬件可用性,本实验使用 InfiniBand,也可以使用英特尔 OPA。

测试之前,关闭主机和目标设备,设置设备间的高速网络。将 Mellanox ConnectX*-3 VPI InfiniBand 适配器安装至主机和目标设备的 PCIe 插槽中,通过 InfiniBand 线缆连接,没有路由器的介入。重启设备后,首先验证 Mellanox 网络适配器是否已安装至主机:

[host-device]$ lspci | grep Mellanox
84:00.0 Network controller:Mellanox Technologies MT27500 Family [ConnectX-3]

然后验证其是否已安装至目标设备:

[knl-sb2 ~]$ lspci | grep Mellanox
01:00.0 Network controller:Mellanox Technologies MT27500 Family [ConnectX-3]

软件安装

主机和目标设备运行 Red Hat Enterprise Linux 7.2。您可以在主机验证 Linux Kernel 是否为最新版:

[host-device]$ uname -a
Linux host-device 3.10.0-327.el7.x86_64 #1 SMP Thu Oct 29 17:29:29 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux

您还可以验证在目标设备上运行的当前操作系统内核:

[knl-sb2 ~]$ uname –a
Linux knl-sb2 3.10.0-327.el7.x86_64 #1 SMP Thu Oct 29 17:29:29 EDT 2015 x86_64 x86_64 x86_64 GNU/Linux

访问此处,获取最新 Oof 软件,并将 Oof 安装至主机,以启用 Oof。本教程安装了面向 Red Hat Enterprise Linux 7.2 (xppsl-1.4.0-offload-host-rhel7.2.tar) 的 Oof 软件 1.4.0 版。如欲获取关于安装的更多信息,请参考文档《英特尔® 至强融核™ 处理器 x200 Offload over Fabric 用户指南》。此外,在主机安装英特尔® Parallel Studio XE 2017,以启用 Oof 支持,特别是由英特尔编译器提供的卸载编程模型支持。

访问此处,获取最新版英特尔至强融核处理器软件,并将其安装在目标设备。本教程中安装了面向 Red Hat Enterprise Linux 7.2 (xppsl-1.4.0-rhel7.2.tar)的英特尔至强融核处理器软件 1.4.0 版。如欲获取关于安装的更多信息,请参考文档《英特尔® 至强融核™ 处理器软件用户指南》。

在主机和目标设备上安装面向 Linux 驱动程序 MLNX_OFED_LINUX 3.2-2 和 Red Hat Enterprise Linux 7.2 的 Mellanox OpenFabrics Enterprise Distribution (OFED),以设置主机和目标设备之间的 InfiniBand 网络。该驱动程序可以通过以下链接下载 www.mellanox.com(导航至Products > Software > InfiniBand/VPI Drivers下载Mellanox OFED Linux)。

基本硬件测试

在主机和目标设备上安装 Mellanox 驱动程序后,测试网卡,以确保 Mellanox InfiniBand HCA 能够正常工作。为了完成这一操作,请连接 InfiniBand 网络,并使用 ibping命令测试网络连接。

首先启动主机的 InfiniBand 和子网管理器,然后显示连接信息:

[knl-sb2 ~]$ sudo service openibd start
Loading HCA driver and Access Layer:                       [  OK  ]

[knl-sb2 ~]$ sudo service opensm start
Redirecting to /bin/systemctl start  opensm.service

[knl-sb2 ~]$ iblinkinfo
CA: host-device HCA-1:
      0x7cfe900300a13b41      1    1[  ] ==( 4X       14.0625 Gbps Active/  LinkUp)==>       2    1[  ] "knl-sb2 HCA-1" ( )
CA: knl-sb2 HCA-1:
      0xf4521403007d2b91      2    1[  ] ==( 4X       14.0625 Gbps Active/  LinkUp)==>       1    1[  ] "host-device HCA-1" ( )

以相同方式在目标设备启动 InfiniBand 和子网管理器,然后显示 InfiniBand 网络每个端口的连接信息:

[knl-sb2 ~]$ sudo service openibd start
Loading HCA driver and Access Layer:                       [  OK  ]

[knl-sb2 ~]$ sudo service opensm start
Redirecting to /bin/systemctl start  opensm.service

[knl-sb2 ~]$ iblinkinfo
CA: host-device HCA-1:
      0x7cfe900300a13b41      1    1[  ] ==( 4X       14.0625 Gbps Active/  LinkUp)==>       2    1[  ] "knl-sb2 HCA-1" ( )
CA: knl-sb2 HCA-1:
      0xf4521403007d2b91      2    1[  ] ==( 4X       14.0625 Gbps Active/  LinkUp)==>       1    1[  ] "host-device HCA-1" ( )

iblinkinfo报告该架构中所有端口的连接信息,一个位于目标设备,一个位于主机。然后,借助 ibping命令测试连接(等同于面向以太网的 ping命令)。利用以下命令启动主机的 ibping服务器:

[host-device ~]$ ibping –S

在目标设备上,利用 ping 命令识别主机端口:

[knl-sb2 ~]$ ibping -G 0x7cfe900300a13b41
Pong from host-device.(none) (Lid 1): time 0.259 ms
Pong from host-device.(none) (Lid 1): time 0.444 ms
Pong from host-device.(none) (Lid 1): time 0.494 ms

同样,在目标设备上启动 ibping 服务器:

[knl-sb2 ~]$ ibping -S

在主机上,利用 ping 命令识别目标设备端口:

[host-device ~]$ ibping -G 0xf4521403007d2b91
Pong from knl-sb2.jf.intel.com.(none) (Lid 2): time 0.469 ms
Pong from knl-sb2.jf.intel.com.(none) (Lid 2): time 0.585 ms
Pong from knl-sb2.jf.intel.com.(none) (Lid 2): time 0.572 ms

通过 InfiniBand (IPoIB) 进行 IP 配置

到目前为止,我们已经验证了 InfiniBand 网络能够正常运行。下一步,我们需要通过 InfiniBand (IPoIB) 配置 IP,才能使用 OoFabric。该配置提供目标 IP 地址,用于通过架构卸载计算。

首先,验证 ib_ipoib驱动程序是否安装:

[host-device ~]$ lsmod | grep ib_ipoib
ib_ipoib              136906  0
ib_cm                  47035  3 rdma_cm,ib_ucm,ib_ipoib
ib_sa                  33950  5 rdma_cm,ib_cm,mlx4_ib,rdma_ucm,ib_ipoib
ib_core               141088  12 rdma_cm,ib_cm,ib_sa,iw_cm,mlx4_ib,mlx5_ib,ib_mad,ib_ucm,ib_umad,ib_uverbs,rdma_ucm,ib_ipoib
mlx_compat             16639  17 rdma_cm,ib_cm,ib_sa,iw_cm,mlx4_en,mlx4_ib,mlx5_ib,ib_mad,ib_ucm,ib_addr,ib_core,ib_umad,ib_uverbs,mlx4_core,mlx5_core,rdma_ucm ib_ipoib

如果未显示 ib_ipoib驱动程序已安装,需要使用以下命令将该模块添加至 Linux 内核:

[host-device ~]$ modprobe ib_ipoib

然后,通过 ifconfig命令在主机列出 InfiniBand 接口 ib0:

[host-device ~]$ ifconfig ib0
ib0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 2044
Infiniband hardware address can be incorrect!Please read BUGS section in ifconfig(8).
        infiniband A0:00:02:20:FE:80:00:00:00:00:00:00:00:00:00:00:00:00:00:00  txqueuelen 1024  (InfiniBand)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

将该接口的 IP 地址配置为 10.0.0.1:

[host-device ~]$ sudo ifconfig ib0 10.0.0.1/24
[host-device ~]$ ifconfig ib0
ib0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 2044
        inet 10.0.0.1  netmask 255.255.255.0  broadcast 10.0.0.255
Infiniband hardware address can be incorrect!Please read BUGS section in ifconfig(8).
        infiniband A0:00:02:20:FE:80:00:00:00:00:00:00:00:00:00:00:00:00:00:00  txqueuelen 1024  (InfiniBand)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10  bytes 2238 (2.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

同理,在目标设备上将 InfiniBand 接口的 IP 地址配置为 10.0.0.2

[knl-sb2 ~]$ ifconfig ib0
ib0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 2044
Infiniband hardware address can be incorrect!Please read BUGS section in ifconfig(8).
        infiniband A0:00:02:20:FE:80:00:00:00:00:00:00:00:00:00:00:00:00:00:00  txqueuelen 1024  (InfiniBand)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[knl-sb2 ~]$ sudo ifconfig ib0 10.0.0.2/24
[knl-sb2 ~]$ ifconfig ib0
ib0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 2044
        inet 10.0.0.2  netmask 255.255.255.0  broadcast 10.0.0.255
Infiniband hardware address can be incorrect!Please read BUGS section in ifconfig(8).
        infiniband A0:00:02:20:FE:80:00:00:00:00:00:00:00:00:00:00:00:00:00:00  txqueuelen 1024  (InfiniBand)
        RX packets 3  bytes 168 (168.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10  bytes 1985 (1.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

最后,利用主机上的 ping命令验证目标设备的新 IP 地址 10.0.0.2,并测试连接:

[host-device ~]$ ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.443 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.410 ms<CTRL-C>

同样地,利用目标设备验证主机的新 IP 地址 10.0.0.1

[knl-sb2 ~]$ ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.313 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.359 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.375 ms<CTRL-C>

SSH 免密码设置(可选)

将工作负载迁移至目标设备时,安全外壳 (SSH) 需要通过目标设备密码登录目标设备以及执行工作负载。为了避免通过人工干预才能完成迁移,必须启用无密码的 ssh登录。为了进行这一操作,首先需要在主机上生成一对身份验证密钥,无需输入密码:

[host-device ~]$ ssh-keygen -t rsa

然后利用 ssh-copy-id命令将主机的新公共密钥添加至目标设备的公共密钥:

[host-device ~]$ ssh-copy-id @10.0.0.2

Offload over Fabric

此时,高速网络已启用并正常运行。为了启用 Oof 功能,您需要在主机安装面向 Linux 的英特尔® Parallel Studio XE 2017。然后,利用以下命令设置您的 shell 环境:

[host-device]$ source /opt/intel/parallel_studio_xe_2017.0.035/psxevars.sh intel64
Intel(R) Parallel Studio XE 2017 for Linux*
Copyright (C) 2009-2016 Intel Corporation.All rights reserved.

以下是用于测试 Oof 函数的示例程序。该示例程序在主机上分配并初始化一个常量 A和若干缓冲区 x, y, z,然后利用 OpenMP 设备构造指令 (#pragma omp target map…)将计算卸载至目标设备。目标指令创建设备数据环境(在目标设备中)。运行时变量 x,yA的值被复制到目标设备中,然后进行计算。目标设备完成计算后,变量 y 的值被复制回主机。在本示例中,目标设备通过 lscpu命令解析 CPU 信息,并生成一组 OpenMP 线程,计算矢量标量积,并将结果与矢量相加。

#include <stdio.h>

int main(int argc, char* argv[])
{
    int i, num = 1024;;
    float A = 2.0f;

    float *x = (float*) malloc(num*sizeof(float));
    float *y = (float*) malloc(num*sizeof(float));
    float *z = (float*) malloc(num*sizeof(float));

    for (i=0; i<num; i++)
    {
       x[i] = i;
       y[i] = 1.5f;
       z[i] = A*x[i] + y[i];
    }

    printf("Workload is executed in a system with CPU information:\n");
    #pragma omp target map(to: x[0:num], A) \
                       map(tofrom: y[0:num])
    {
        char command[64];
        strcpy(command, "lscpu | grep Model");
        system(command);
        int done = 0;

        #pragma omp parallel for
        for (i=0; i<num; i++)
        {
            y[i] = A*x[i] + y[i];

            if ((omp_get_thread_num() == 0) && (done == 0))
            {
               int numthread = omp_get_num_threads();
               printf("Total number of threads:%d\n", numthread);
               done = 1;
            }
        }
    }

    int passed = 0;

    for (i=0; i<num; i++)
        if (z[i] == y[i]) passed = 1;

    if (passed == 1)
        printf("PASSED!\n");
    else
        printf("FAILED!\n");

    free(x);
    free(y);
    free(z);

    return 0;
}

利用英特尔编译器选项 -qoffload-arch=mic-avx512编译该 OpenMP 程序,表示卸载部分专为第二代英特尔至强融核处理器构建。执行程序之前,将环境变量 OFFLOAD_NODES设置为目标设备的 IP 地址(本例中为 10.0.0.2),表示高速网络已被使用。

[host-device]$ icc -qopenmp -qoffload-arch=mic-avx512 -o OoF-OpenMP-Affinity OoF-OpenMP-Affinity.c

[host-device]$ export OFFLOAD_NODES=10.0.0.2

[host-device]$ ./OoF-OpenMP-Affinity
Workload is executed in a system with CPU information:
Model:                 87
Model name:            Intel(R) Xeon Phi(TM) CPU 7250 @000000 1.40GHz
PASSED!
Total number of threads:268

需要指出的是,卸载过程由英特尔® 协处理器卸载基础架构(英特尔® COI)内部处理。默认情况下,卸载代码运行时,目标设备中 OpenMP 线程的全部可用。目标设备共有 68 个内核,英特尔 COI 后台程序在目标设备的一个内核上运行时,其它 67 个内核为可用;总线程数为 268(4 个线程/内核)。您可以利用 coitrace命令跟踪所有的英特尔 COI API 调用:

[host-device]$ coitrace ./OoF-OpenMP-Affinity
COIEngineGetCount [ThID:0x7f02fdd04780]
        in_DeviceType = COI_DEVICE_MIC
        out_pNumEngines = 0x7fffc8833e00 0x00000001 (hex) :1 (dec)

COIEngineGetHandle [ThID:0x7f02fdd04780]
        in_DeviceType = COI_DEVICE_MIC
        in_EngineIndex = 0x00000000 (hex) :0 (dec)
        out_pEngineHandle = 0x7fffc8833de8 0x7f02f9bc4320

Workload is executed in a system with CPU information:
COIEngineGetHandle [ThID:0x7f02fdd04780]
        in_DeviceType = COI_DEVICE_MIC
        in_EngineIndex = 0x00000000 (hex) :0 (dec)
        out_pEngineHandle = 0x7fffc88328e8 0x7f02f9bc4320

COIEngineGetInfo [ThID:0x7f02fdd04780]
        in_EngineHandle = 0x7f02f9bc4320
        in_EngineInfoSize = 0x00001440 (hex) :5184 (dec)
        out_pEngineInfo = 0x7fffc8831410
                DriverVersion:
                DeviceType:COI_DEVICE_KNL
                NumCores:68
                NumThreads:272

<truncate here>

OpenMP* 线程相似性

上述程序的结果显示了目标设备上运行的默认线程数量 (272),但是,您可以明确设置目标设备上运行的线程数量。一种方法是通过主机上的环境变量来修改目标设备的执行环境。首先,定义一个专门针对目标设备的环境变量前缀,将该前缀添加至 OpenMP 线程相似性环境变量。例如,以下环境变量设置配置卸载运行时使用 8 个目标设备线程:

[host-device]$ $ export MIC_ENV_PREFIX=PHI
[host-device]$ $ export PHI_OMP_NUM_THREADS=8

英特尔 OpenMP 运行时扩展 KMP_PLACE_THREADKMP_AFFINITY环境变量可以将线程绑定至物理处理单元(也就是内核)(如欲获取更多信息,请参考“英特尔® C++ 编译器用户和参考指南”中的线程相似性接口章节)。例如,以下环境变量设置配置卸载运行时使用 8 个相邻线程:

[host-device]$ $ export PHI_KMP_AFFINITY=verbose,granularity=thread,compact
[host-device]$ $ ./OoF-OpenMP-Affinity

您也可以通过 OMP_PROC_BIND环境变量使用 OpenMP 相似性。例如,可以通过以下命令重复以上范例(使用 OMP_PROC_BIND运行 8 个相邻线程):

[host-device]$ $ export MIC_ENV_PREFIX=PHI
[host-device]$ $ export PHI_KMP_AFFINITY=verbose
[host-device]$ $ export PHI_OMP_PROC_BIND=close
[host-device]$ $ export PHI_OMP_NUM_THREADS=8
[host-device]$ $ ./OoF-OpenMP-Affinity

 或者运行 8 个线程,并利用以下命令分散线程:

[host-device]$ $ export PHI_OMP_PROC_BIND=spread
[host-device]$ $ ./OoF-OpenMP-Affinity

结果在下表中列出:

OpenMP* 线程数量内核数量
00
110
219
331
439
548
656
765

如欲运行 8 个线程,2 个线程/内核(共计 4 个内核),请执行以下命令:

[host-device]$ export PHI_OMP_PROC_BIND=close;
[host-device]$ export PHI_OMP_PLACES="cores(4)"
[host-device]$ export PHI_OMP_NUM_THREADS=8
[host-device]$ $ ./OoF-OpenMP-Affinity

结果在下表中列出:

OpenMP* 线程数量内核数量
00
10
21
31
42
52
63
73

总结

该教程详细介绍了如何设置并运行一个 Oof 应用以及如何安装硬件和软件。本文示例使用的是 Mellanox InfiniBand 主机通道适配器,也可以使用英特尔 OPA。示例代码是一个 OpenMP 卸载编程模型应用,展示了利用高速网络将运行在英特尔至强处理器主机上的运算卸载至英特尔至强融核处理器目标设备。本教程还展示了如何面向英特尔至强融核处理器编译并运行卸载程序,以及如何控制英特尔至强融核处理器上的 OpenMP 线程相似性。

参考文献

关于作者

Loc Q Nguyen拥有达拉斯大学 MBA 学位、麦吉尔大学电子工程专业硕士学位以及蒙特利尔理工学院电子工程专业学士学位。目前在英特尔公司软件及服务事业部担任软件工程师。研究领域包括计算机网络、并行计算和计算机图形。

用于亚洲期权定价的 Monte Carlo 模拟

$
0
0

本文对基于多核处理器和众核 (MIC) 协处理器的异构英特尔架构系统进行了一项性能优化练习。

注:本实验根据《利用英特尔至强融核协处理器进行并行编程与优化》("Parallel Programming and Optimization with Intel Xeon Phi Coprocessors",2015 年第二版)中的第 4.7.1 节和第 4.7.2 节内容操作。如欲获取本书,请访问xeonphi.com/book

本文讨论了如何在异构集群中实现 MPI 应用的负载平衡。本文涉及的源代码来自用于亚洲期权定价的 Monte Carlo 模拟。为了便于练习,模拟的实际实施并不重要,如果您有兴趣了解关于模拟的更多知识,请访问 Colfax Research 网站。

亚洲期权代码示例链接:https://github.com/ColfaxResearch/Asian-Options

  1. 学习并编译 "workdistribution.cc"。然后在所有节点(包括 MIC)间运行 MPI 应用,每个节点运行一个进程。

    您会发现负载不平衡,即某个节点比其它节点完成得早。

  2. 维持负载平衡的一个简单方法就是根据目标系统的差异,不均匀地分配任务。实施一个调试变量 "alpha"(应为 typefloat 或 double),MIC 接受的工作负载数量是 CPU 接受的工作负载数量的 alpha 倍。每个节点应通过计算决定处理哪个选项。为了执行这一操作,使用函数输入 "rankTypes",后者存储了全球所有的节点类型(CPU 或 MIC)。如果“i”队列节点位于协处理器,则"rankTypes[i]"为 "1";如果“i”队列节点位于 CPU,则 "rankTypes[i]"为 "0"。请确保每一个选项都被计算在内。

    编译并运行该应用。然后,尝试寻找提供最佳性能的 "alpha"值。

  3. 尽管之前的实施更为简单,但是存在缺陷 - alpha 值取决于集群。为了使应用独立于其运行的集群,请实施 boss-worker 模式,在该模式下,worker 完成工作后,由 boss 将工作分配给 worker。

    编译并运行代码,以查看性能。请记住,Boss 进程所在的节点应该有两个进程。

    提示:为了实施 boss worker 模式,您将需要一个包含两个 while 循环的 if 语句。worker 循环应将队列发送到主机,并接收需要计算的索引。主机应使用 MPI_ANY_SOURCE 接收队列,并将下一个索引发送到其接收的 worker 队列。等到没有需要模拟的选项时,boss 应发送一个" terminate"索引(如 -1 索引)。当 worker 收到 "terminate"索引时,应当退出 while 循环。当 "terminate"发送到每个进程后,主机应当退出 while 循环。最后,请不要忘记在运行 MPI_Reduce 之前首先运行 MPI_Barrier,以确保在模拟结束前完成所有进程。

亚洲期权 代码 GitHub 链接:https://github.com/ColfaxResearch/Asian-Options

英特尔® 至强® 处理器和英特尔® 至强融核™ 协处理器利用通用代码实现多线程方阵转置

$
0
0

就地矩阵转置是一种标准的线性代数操作,属于内存带宽限制操作。转置的理论最高性能可达到内存副本带宽。然而,由于转置操作中内存访问的非连续性,实际性能通常低于理论最高性能。转置率与内存副本带宽的比率是衡量转置算法效率的指标。

本文展示并讨论了如何利用 C 语言高效实施并行就地方阵转置。大型矩阵在英特尔® 至强® 处理器上的转置率高达 49 GB/秒(效率为 82%);在英特尔® 至强融核™ 协处理器上的转置率高达 113 GB/秒(效率为 67%)。使用基于编译指示的编译器提示和编译器参数对代码进行调优。OpenMP* 处理代码中的线程并行,英特尔编译器自动实施矢量化。借助这个方法,可以使 CPU 和 MIC 可执行架构共用一个 C 代码,两者都展现了高效性。使用英特尔至强融核协处理器 7110p 进行性能指标评测。

执行 ./benchmark.sh 脚本,以运行性能指标评测。

其中的 Makefile 和./benchmark.sh 脚本是专为 Linux 而设计的。

需要将英特尔 C++ 编译器安装到系统之后,才能编译 CPU 代码。

为了编译并运行 MIC 平台代码,需要在配有英特尔至强融核协处理器的系统上安装 MIC 平台软件堆栈 (MPSS),并运行

方阵多线程转置代码(GitHub 链接为:https://github.com/ColfaxResearch/Transposition)

 

趋势观察:2017 年展望

$
0
0

2016 年,许多最具创新性的技术专注于现实与虚拟世界的融合,比如使用 GPS 和摄像头的增强现实游戏《口袋妖怪 GO》*、通过通讯平台提供实时信息和帮助安排旅行的全新聊天机器人等。进入 2017 年,使用技术连接周围世界的方式将进一步增多,而且事物之间的通信及支持它们的软件会变得更加复杂。

无论您是关注消费类应用还是对 B2B 感兴趣,2017 年您都需要关注下列几大技术趋势。

人工智能 (AI) 和机器学习

人工智能曾经只是科幻小说描述的幻想,如今在不断发展,拓展着人类对可能性的定义。从自动驾驶汽车到智能产品推荐再到聊天机器人,人工智能的身影无处不在,其基本宗旨在于打造可感知、推理、行动并根据经验进行调整的机器。在物联网设备和海量数据不断增多的情况下,互联程度会继续提升,需要处理的信息也会增加,为此我们需要继续推进技术进步。

2016 年的一项重大新闻是,Google 和 Microsoft 在其云环境中添加了人工智能服务,使得大量规模较小的企业和初创公司能够利用人工智能技术。2017 年,我们预计更多公司将把人工智能集成到其产品中,而随着这一市场的增长,相关合作也必将增多。了解设备与系统如何有效协作大有裨益,聪明的公司和开发人员将会在这方面投入大量和资源。他们不会各自为政,而是会加强彼此的协作与整合。

英特尔在做什么?

凭借可靠的硬件、优化的框架和丰富的资源,英特尔能够推动人工智能的发展。

优化的框架 – Caffe* 是图像识别领域最流行的社区应用之一,Theano* 专为帮助编写深度学习模型而设计。两种框架都为与英特尔® 架构一起使用进行了优化。了解如何安装和使用这些框架,点击此处查找各种有用的资料库。

硬件 - 英特尔® 至强融核™ 处理器产品家族 – 这些多核处理器可为机器学习和深度学习工作负载提供强大、高度并行的性能。点击此处简要了解使用英特尔® 架构的深度学习,并点击此处详细了解英特尔® 至强融核™ 处理器产品家族可为深度学习提供的性能优势。

了解更多信息:

虚拟助手并非新鲜事物。过去几年,消费者逐步接受了虚拟助手,比如手机上随时可用的 Siri* 以及放置在厨房柜台上的 Alexa*,它们能够及时回答任何问题。2016 年的一项变化是,业内人士大力推动虚拟助手与其他系统和服务的深度集成,以帮助用户访问第三方软件,或通过与虚拟助手交互便可处理较为复杂的交易。6 月,Apple 最终向第三方开发人员开放了 Siri*,释放了广泛的全新可能性。

2017 年,我们需要寻找全新合作机会,部署更多数字服务,以进一步增强通信能力。虚拟助手的出现意味着我们无需在 Google 中键入搜索词,而是能够以平常说话的方式提出请求和问题(例如,“我今天应该穿夹克吗?”),然后虚拟助手会列出您需要采取的一系列步骤或行动。例如,查看天气预报、查看时间表和查看衣柜的衣物储备,同时使用人工智能不断改进结果的质量和准确性。随着虚拟助手的集成度不断提高,它们能处理的任务将继续变得的更加复杂,最终为人们带来更多便利。

借助物联网,生活中的日常事物将变得更加智能。只要配备芯片和传感器,鞋带、灯泡、电源插座等日常用品将不再局限于以前的单一功能,结合能够分析周围世界的软件,还可以帮助我们跟踪和了解周围世界,获得更多便利,例如预测制造领域即将出现的维修需求、离开房间时关闭灯光、鼓励我们加强身体锻炼。

2017 年,不同设备能够相互并与其他事物通信,帮助彼此做出决策,这种场景尤其是智能建筑物和城市的显著特征。随着更多数据被收集和更多系统开放合作,我们可以构建真正有趣的模型。例如,如果雨量计可以测量降水量,而且这一信息可与最新的天气预报相整合,那么智能建筑物可以决定是否应该打开前门灯光了。另一个充满机遇的领域是制造业。传感器和芯片可帮助预测维修需求,以节省相关成本和时间。

英特尔在做什么?

英特尔提供了广泛的硬件选项,包括英特尔® Edison英特尔® Curie模块与面向企业的英特尔® 物联网网关,以及入门软件工具和代码示例、云和分析工具支持。英特尔还在全球主办和参与了许多黑客马拉松比赛及其他与物联网相关的活动

了解更多信息:

虚拟现实是 2016 年的热门话题,但尚未真正成为主流技术。希望 2017 年这种情况能有所改变。今年,Microsoft 将发布全新 HoloLens,Facebook 已经与 Oculus Rift* 一起预先展示了一些全新的办公应用。随着人工智能的持续改进和互联设备的增多,虚拟现实等沉浸式体验与现实世界、其他设备、甚至其他虚拟体验的连接也会增强。人工智能在商业领域的用例也会增多。

虚拟现实或增强现实在游戏等消费类应用或足球比赛、音乐会等活动中拥有广泛的应用前景,举例来说,您甚至无需离开沙发就可身临其境般体验这些活动。该技术在 B2B 市场也蕴含着大量商机,尤其在培训方面。

该技术可用于培训人类针对外太空、深海或人体内部等难以到达的环境开展相关工作。外科医生可使用虚拟现实实施外科技术,水下技术员可学习如何实施复杂的维修工作。人工智能也可广泛应用于工业领域,如工厂机械数字叠加(可用于提供培训和帮助维修)。

2017 年,随着虚拟现实进一步成为主流技术,这些功能性和商业方面的用例将会大放异彩。

英特尔在做什么?

英特尔致力于实现融合现实,它能够削弱虚拟感并增强现实感。在这种体验中,您能够看到现实世界,但也可看到并操作数字对象。该体验不会限制您接下来去哪里,支持您改变场景,或与重要人物共度重要时刻,无论他们位于真实世界的什么地方。

了解更多信息:

您基本上可在 Facebook*、Skype* 和其他主流通讯平台上与聊天机器人进行通信。例如,您无需登录零售商的网站购买新腰带,只需使用 Facebook Messenger* 向零售商发送讯息,告诉他们您需要哪一款、哪个尺码的腰带。再比如,您可以向万豪酒店* 发送讯息,告诉他们您即将开始的旅行的日期及需要的客房类型,或咨询即将推出的特别优惠。2016 年,Facebook* 在 Messenger* 中推出了聊天机器人,允许公司提供自动客户支持、电子商务引导、内容和交互式体验等。在接下来的一年内,我们或许能看到这方面的更多进展。

2017 年,通信应用和其他公司之间的整合预计将进一步加强,相关通讯平台和一些现有的产品应用预计将支持部分聊天机器人交互。一些公司会兴趣采用定制聊天机器人,一些公司可能希望使用现成的版本。此外,聊天机器人预计将具备更多功能,如更为复杂的交易和电子商务支持及增强的人工智能,后者支持聊天机器人模拟某些人,融入幽默和特定声音等因素。

相比我们上面讨论的趋势,下面四种趋势尚未得到发展,但同样令人期待。本文探讨的重点是如何更好地支持这种正在打造的全新技术,并让其发挥更大的效用。我们将如何访问及保护正在收集的数据?如何可如何提升效率,通过合作充分利用互联设备和系统?阅读更多内容,占得先机。

区块链

几年前,比特币* 风靡一时,但在 2017 年,它的底层技术将吸引我们的最大关注度。它是什么,为何重要?本质上,区块链是一种在许多不同电脑之间分配数据库的方式,用于维护日益增多的记录(称为区块)。在专门加密的对等网络中,每个区块连接至前一个区块,该网络能够提供强大的安全保护功能,可防止篡改和修改。该技术可用于记录数字货币,如比特币*,但也有许多其他的潜在用途,能够改变许多不同行业存储和传输数据的方式。由于数据由社区记录和共享,因此不仅数据的安全性显著提高,而且其透明度和可信度也得到了保障。社区的每个成员都拥有记录的副本,所有人都必须验证更新。这一技术将在各行各业产生巨大的影响力,如金融、医疗、社交网络、忠诚度和奖励计划、合同、音乐发行、资产管理、身份验证、所有权登记、供应链、甚至电子投票等。

它能够用于几乎任何需要保持准确记录的行业,例如在娱乐业,从业人员往往大费周章地管理活动的票务工作,而且通常需要花钱聘请第三方厂商提供帮助。使用区块链,粉丝可以验证电子钱包之间的所有权转让,无需担心收到的 PDF 门票被出售给多人。

2016 年,区块链进行了大规模试验;2017 年,它将大显身手。作为一种全新技术,区块链尚不具备大量有用资产,因此其增长仍将比较有限,并可能主要惠益于金融行业。但我们应该看到,多个网络的标准和协议正在制定中,相关最佳实践也在逐步形成,这将为未来的合作铺平道路。

数字双胞胎 (Digital Twin)

数字双胞胎表示物理事物的软件模型。通过使用传感器数据了解真实事物的当前状态,并可视化表现其发生的变化,数字双胞胎能为我们提供改进运营和提升价值的全新机会。比如,在查看包含相关数据(如工厂机器性能)的报告时,我们需要认真审阅这些数据,形象表示产品在不同工位中的状况,以了解产品生产情况,及如何改进运营,或预测哪部分很快将发生问题。借助数字双胞胎,我们能够切实了解产品在各个工位中的情况,以了解产品的特征。我们无需查看相关数字,而是可以在虚拟工厂中看到产品的实际情况,以及可反映问题产生过程的趋势线。

在一定程度上,您可将数字双胞胎视为人工智能、物联网和虚拟现实/增强现实的混合体。根据来自传感器和设备(如工厂机器、运动员在训练时佩戴的可穿戴设备)的数据,我们可以使用虚拟现实/增强现实可视化展示工厂或运动员的状况,然后发挥人工智能的长项:感知、推理、行动和调整。各种传感器和设备为我们收集了海量的信息,数字双胞胎为利用这些信息提供了一种全新的方法。

Gartner 表示,在未来五年内,数亿个事物将配备数字双胞胎,它们将用于制定设备维修计划、确保工厂高效运营、预测设备故障、提升效率和开发新产品。这些数字双胞胎将成为现实世界数据和数字世界信息之间的重要纽带。

网格应用和服务架构 (MASA)

随着全新在线设备的持续开发和使用,我们将需要 IT 系统支持这些设备相互通信,这正是网格应用和服务架构的用武之地。展望 2017 年及更远未来,网格应用和服务架构将与其他技术一起不断发展。网格应用和服务架构能够在多个层面和传统边界展示 API,将 Web、移动、桌面和物联网应用整合起来,从而提供连续、优化的体验。

从根本上来说,它旨在连接多个终端,以提供无缝体验。它需要比传统架构更快,支持跨多个设备和应用协作,在云环境内外运行,满足用户快速变化的需求。

自适应安全架构

随着设备的智能和互联程度不断提高,我们需要采用更有效的方式保护数据和系统。自适应安全架构可帮助我们将强大的人工智能技术引入安全领域,不仅要采取适当的安全措施,而且要预测、阻止/防止、检测和报告问题,在发生威胁时进行有效管理,并获取改进洞察。借助 ASA,更智能的电脑和设备将能够学习如何加强自我保护。

在处理海量安全数据方面,采用智能、灵活的战略比以往更为重要。为实现真正的自适应性和出色的安全性,我们不能仅仅记录数据或向操作员发出警告。架构本身需要在数秒之内做出决策和响应,2017 年,随着 ASA 的进一步发展,我们将实现这一目标。

2017 年,许多前沿技术的发展值得我们期待,许多领域还等待我们去发掘。如果您对其中的一个领域感兴趣,请继续进行探索和开展相关试验。如需查看更多文章、了解更多工具或与其他开发人员交流,请访问英特尔® 开发人员专区

选择物联网项目编程语言

$
0
0

物联网生态系统

为了帮助您选择物联网项目使用的语言,您首先必须了解物联网生态系统。这一点非常重要,因为不同级别的软件和固件所使用的处理器架构和资源相差很大。

首先,对用于软件开发的物联网设备进行一个简单的分类(见图 1)。

图 1.物联网设备分类

位于底部的是边缘设备。这些设备和周围的世界互动,代表了可穿戴和其他互联设备。这些设备采集并创造数据,通过致动器与世界互动。

中间的级别是网关。这些设备属于中间设备,用于将数据传输到其它系统,以进行处理。网关也可以从许多边缘设备中收集数据,提供一条连接终端设备的控制路径。

位于顶部的是云。云是一系列可扩展计算、网络和存储资源,能够对终端设备和网关收集的数据进行存储、分析和可视化处理。

3 个级别的示例包括面向终端设备的英特尔® Galileo 开发板和英特尔® Curie™ 计算模块、网关级别的英特尔® 物联网网关和云级别的 Wind River* Helix* Lab Cloud。

由于物联网生态系统分为多个层面,现在让我们来了解每个级别所使用的语言。

终端设备

以可穿戴设备为代表的终端设备,由于受到空间和功率的限制,通常采用资源受限的嵌入式系统。如图 2 所示,英特尔® Curie™ 模块和纽扣差不多大,由硬币大小的小型电池供电。由于英特尔® Curie™ 模块资源极少,适合它的常用语言包括汇编语言和 C 语言。尽管 C 语言是嵌入式固件开发的通用语言,但有时仍需将尽可能多的指令写入设备。在这种情况下,汇编语言是一个绝佳的选择。其缺点是需要较长的开发时间,时间长短取决于您对该语言的熟练程度。

图 2.英特尔® Curie™ 计算模块

英特尔® Edison 开发板是终端设备的另一个例子(见图 3),您可以将它用于可穿戴设备或通用物联网产品中。和集成了一台微控制器的英特尔® Curie™ 模块不同,英特尔® Edison 开发板采用双核英特尔® 凌动™ 处理器,计算能力显著增强(和 SD 卡一样大)。由于英特尔® Edison 开发板运行 Linux*,C 语言是比较理想的选择,但是您也可以使用其它语言,包括 Python* 和 Node.js*。Python* 适合快速构建原型和产品部署,但是性能低于本地编译的 C 语言。如果您使用英特尔® XDK,可以利用 Node-RED* 运行 Node.js* (JavaScript*)。Node-RED* 帮助您轻松构建和运行数据流,提供了一种图形开发方法。运用 JavaScript* 语言知识能使该环境变得更强大。

图 3.英特尔® Edison 开发板

网关

在网关级别,来源于各种设备的数据通过若干总线传输至网关,进行数据传送和分析,因此,网关的计算能力显著提升。由于计算性能卓越,网关可以运行更强大的语言或解释性语言,进一步提升性能。

英特尔® 物联网网关提供各种设计,从单个芯片上的单核英特尔® Quark™ 系统,到四核英特尔® 凌动™ 或英特尔® 酷睿™ 处理器(见图 4)。这些平台支持 Wind River Linux* 7 或 Snappy Ubuntu* Core (Linux*)。

图 4.一台英特尔® 物联网网关

除了 C 语言和 C++ 语言(后者适合更高性能的设备),您还可以使用 Python*,但是需要更高的执行速度。还可以使用基于 JavaScript 的 Node.js*,后者非常适合创建或连接至 web 服务和云服务。

云级别的计算能力显著增强,语言选择也更为丰富。云的内部部署若干台服务器,这些服务器采用高能效英特尔凌动和英特尔酷睿处理器,以及具备最高计算密度的英特尔® 至强® 处理器。云内部编写的应用满足各种需求,同样地,云内部使用的语言也有很大的差异。您可以利用大数据框架(如 Apache Hadoop*)来处理物联网边缘设备产生的海量数据。基于 Hadoop 的查询语言(如 Apache Hive*)支持借助类似结构化查询语言 (SQL) 的查询对大型数据集进行计算。Apache Pig* 有助于 Pig Latin 脚本语言对大型数据集进行实验。

数据分析和可视化处理也是云内部的关键应用,受多种编程语言支持。R 语言是用于统计计算和可视化的常见语言和环境,最近日益流行。Julia 语言也是不错的选择。Julia 是一种高性能的动态语言,在设计时充分考虑了云计算。

您可以使用几种语言创建 web 服务,发挥云内部数据的价值,这些语言包括 JavaScript*、Node.js* 以及服务器端和客户端 Java*。由于云内部存在众多框架和支持语言(如 Rails 和 Ruby),因此,云级别的语言选择非常丰富,且日益扩大。

总结

选择项目的编程语言需要考虑目标环境(包括处理器)和可用的资源。由于可用资源规模庞大,在云内部开发软件具有许多可能性,但是针对小型微控制器开发嵌入式固件时,需要更有效地控制,尽量减少指令数量,最大限度地提高执行速度、强化资源管理。

下表简单概括了本文提及的语言,并明确了主要使用模式:

  • 汇编语言:在原生指令集内开发固件,为资源受限的系统(如边缘设备)提供最佳控制。
  • C/C++:比汇编语言更为高级,C 和 C++ 两种语言支持创建资源受限型代码,提供出色的可读性和可维护性。C 语言的优势使其广泛存在于各个使用模式中。
  • Python*:一种能够简化原型构建的解释性语言,您还可以将它用户生产环节。Python* 支持大量的库和模块,可以利用较少的代码完成更多的任务。适用于更强大的边缘设备、网关,甚至云。
  • JavaScript*/Node.js*:一种常见的语言和运行时,支持开发可扩展网络应用,可以在多种使用模式下应用。
  • Node-RED*:利用 Node-RED* 进行视觉开发,更轻松地创建数据流,包括传感器和致动器。如果您熟悉 JavaScript*,这些数据流会更强大。您可以在网关或更为强大的边缘设备中使用语言,如 Edison 开发板支持的边缘设备。
  • HiveQL:如果您正在使用 Hive(基于 Hadoop),您可以通过 HiveQL 在云环境中处理海量数据集。
  • Pig:利用 Pig Latin 处理大数据,在云内部快速开发脚本,进行简单的数据集实验。
  • R 语言:一种日益流行的用于数据处理和可视化的统计计算语言,您可以利用 R 语言在云环境中进行数据挖掘。R 语言也是一种开源语言。
  • Julia:另一种在云环境中对数据进行处理和可视化的高性能语言,Julia 语言也是一种开源语言。在设计该语言时充分考虑了并行性,包含分布式计算的关键要素。
  • Java*:一种常见的面向 Web 的服务器端和客户端语言,在云内部开发 web 和 web 服务时非常实用。
Viewing all 583 articles
Browse latest View live