Xeon Phi 《协处理器高性能编程指南》随书代码整理 part 3
▶ 第二章,几个简单的程序
● 代码,单线程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h> #define SIZE (1024*1024)
#define MAXFLOP_ITER 100000000
#define LOOP_COUNT 128
#define FLOP_PER_CALC 2 float fa[SIZE] __attribute__((align()));
float fb[SIZE] __attribute__((align())); double dtime()
{
struct timeval mytime;
gettimeofday(&mytime, (struct timezone*));
return (double)(mytime.tv_sec + mytime.tv_usec*1.0e-6);
} int main(int argc, char *argv[])
{
const float a = 1.1; printf("Initializing\r\n");
for (int i = ; i < SIZE; i++)
{
fa[i] = (float)i + 0.1;
fb[i] = (float)i + 0.2;
} printf("Starting Compute\r\n");
double time_b, time_e;
time_b = dtime();
for (int j = ; j < MAXFLOP_ITER; j++)
{
for (int k = ; k < LOOP_COUNT; k++)
fa[k] = a * fa[k] + fb[k];
}
time_e = dtime(); double gflops = 1.0e-9 * LOOP_COUNT * MAXFLOP_ITER * FLOP_PER_CALC;
printf("GFlops = %10.3lf, Secs = %10.3lf, GFlops per sec = %10.3lf\r\n", gflops, time_e - time_b, gflops / (time_e - time_b)); return ;
}
■ 输出结果
GFlops = 25.600, Secs = 1.464, GFlops per sec = 17.484
● 单核心两线程的 OpenMP(注意总计算量提升了,而不是固定计算量看运行时间减少)
int main(int argc, char *argv[])
{
const float a = 1.1;
int i, j, k, numthreads; // 循环变量放到外边来 omp_set_num_threads(); // 运行时设置 OpenMP 参数
kmp_set_defaults("KMP_AFFINITY=compact"); #pragma omp parallel
#pragma omp master
numthreads = omp_get_num_threads(); printf("Initializing\r\n");
#pragma omp parallel for
for (i = ; i < SIZE; i++)
{
fa[i] = (float)i + 0.1;
fb[i] = (float)i + 0.2;
}
printf("Starting Compute on %d threads\r\n", numthreads);
double time_b, time_e;
time_b = dtime();
#pragma omp parallel for private(j, k)
for (i = ; i < numthreads; i++)
{
int offset = i * LOOP_COUNT;
for (j = ; j < MAXFLOP_ITER; j++)
{
for (k = ; k < LOOP_COUNT; k++)
fa[k + offset] = a * fa[k + offset] + fb[k + offset];
}
}
time_e = dtime(); double gflops = 1.0e-9 * numthreads * LOOP_COUNT * MAXFLOP_ITER * FLOP_PER_CALC;
printf("GFlops = %10.3lf, Secs = %10.3lf, GFlops per sec = %10.3lf\r\n", gflops, time_e - time_b, gflops / (time_e - time_b)); return ;
}
■ 输出结果
GFlops = 51.200, Secs = 1.464, GFlops per sec = 34.968
● 线程数、线程亲缘性调整
// 替换
omp_set_num_threads();
kmp_set_defaults("KMP_AFFINITY=compact");
// 替换为
omp_set_num_threads();
kmp_set_defaults("KMP_AFFINITY=scatter");
■ 输出结果
GFlops = 2867.200, Secs = 1.619, GFlops per sec = 1771.298
● 代码,带宽测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <omp.h> #define REAL double
#define SIZE (1000*1000*64)
#define MAXFLOP_ITER 1000
#define FLOP_PER_CALC 2 REAL fa[SIZE] __attribute__((align()));
REAL fb[SIZE] __attribute__((align()));
REAL fc[SIZE] __attribute__((align())); double dtime()
{
struct timeval mytime;
gettimeofday(&mytime, (struct timezone*));
return (double)(mytime.tv_sec + mytime.tv_usec*1.0e-6);
} int main(int argc, char *argv[])
{
const REAL a = 1.1;
int i, j; omp_set_num_threads();
kmp_set_defaults("KMP_AFFINITY=scatter"); printf("Initializing\r\n");
#pragma omp parallel for
for (i = ; i < SIZE; i++)
{
fa[i] = (REAL)i + 0.1;
fb[i] = (REAL)i + 0.2;
} #pragma omp parallel
#pragma omp master
printf("Starting BW Test on %d threads\r\n", omp_get_num_threads());
double time_b, time_e;
time_b = dtime();
for (i = ; i < MAXFLOP_ITER; i++)
{
#pragma omp parallel for
for (j = ; j < SIZE; j++)
fa[j] = fb[j];
}
time_e = dtime();
double gbytes = 1.0e-9 * MAXFLOP_ITER * SIZE * FLOP_PER_CALC * sizeof(REAL);
printf("Gbytes = %10.3lf, Secs = %10.3lf, GBytes per sec = %10.3lf\r\n", gbytes, time_e - time_b, gbytes / (time_e - time_b)); return ;
}
■ 输出结果
Starting BW Test on threads
Gbytes = 1024.000, Secs = 10.293, GBytes per sec = 99.488
● 代码,offload 模式(注意全局变量和编译选项的调整)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <omp.h> #define SIZE (1024*512)
#define MAXFLOP_ITER 100000000
#define LOOP_COUNT 128
#define FLOP_PER_CALC 2 __declspec (target(mic)) float fa[SIZE] __attribute__((align())); // 声明 mic 上的存储类型
__declspec (target(mic)) float fb[SIZE] __attribute__((align())); double dtime()
{
struct timeval mytime;
gettimeofday(&mytime, (struct timezone*));
return (double)(mytime.tv_sec + mytime.tv_usec*1.0e-6);
} int main(int argc, char *argv[])
{
const float a = 1.1;
int i, j, k, numthreads; omp_set_num_threads();
kmp_set_defaults("KMP_AFFINITY=scatter");
#pragma offload target (mic)// 声明需要使用 mic 的 offload 模式
#pragma omp parallel
#pragma omp master
numthreads = omp_get_num_threads(); printf("Initializing\r\n");
#pragma omp parallel for
for (i = ; i<SIZE; i++)
{
fa[i] = (float)i + 0.1;
fb[i] = (float)i + 0.2;
}
printf("Starting Compute on %d threads\r\n", numthreads);
double time_b, time_e;
time_b = dtime();
#pragma offload target (mic)// 声明需要使用 mic 的 offload 模式
#pragma omp parallel for private(j, k)
for (i = ; i<numthreads; i++)
{
int offset = i * LOOP_COUNT;
for (j = ; j < MAXFLOP_ITER; j++)
{
#pragma vector aligned// 强制向量对齐
for (k = ; k < LOOP_COUNT; k++)
fa[k + offset] = a * fa[k + offset] + fb[k + offset];
}
}
time_e = dtime(); double gflops = 1.0e-9 * numthreads * LOOP_COUNT * MAXFLOP_ITER * FLOP_PER_CALC;
printf("GFlops = %10.3lf, Secs = %10.3lf, GFlops per sec = %10.3lf\r\n", gflops, time_e - time_b, gflops / (time_e - time_b)); return ;
}
■ 输出结果
Starting Compute on threads
GFlops = 5734.400, Secs = 2.976, GFlops per sec = 1927.124
Xeon Phi 《协处理器高性能编程指南》随书代码整理 part 3的更多相关文章
- Xeon Phi 《协处理器高性能编程指南》随书代码整理 part 1
▶ 第三章,逐步优化了一个二维卷积计算的过程 ● 基准代码 #include <stdio.h> #include <stdlib.h> #include <string ...
- Xeon Phi 《协处理器高性能编程指南》随书代码整理 part 4
▶ 第五章,几个优化 ● 代码 #include <stdio.h> #include <stdlib.h> #include <math.h> #define S ...
- Xeon Phi 《协处理器高性能编程指南》随书代码整理 part 2
▶ 第四章,逐步优化了一个三维卷积计算的过程 ● 基准代码 #include <stdio.h> #include <stdlib.h> #include <string ...
- Xeon Phi 编程备忘
▶ 闲鱼的 Xeon Phi 3120A 配办公室的新 Xeon 服务器,记录一下环境安装过程. ● 原本尝试搭 Ubuntu 服务器,参考[https://software.intel.com/en ...
- Python猫荐书系列之五:Python高性能编程
稍微关心编程语言的使用趋势的人都知道,最近几年,国内最火的两种语言非 Python 与 Go 莫属,于是,隔三差五就会有人问:这两种语言谁更厉害/好找工作/高工资…… 对于编程语言的争论,就是猿界的生 ...
- 《高性能javascript》一书要点和延伸(上)
前些天收到了HTML5中国送来的<高性能javascript>一书,便打算将其做为假期消遣,顺便也写篇文章记录下书中一些要点. 个人觉得本书很值得中低级别的前端朋友阅读,会有很多意想不到的 ...
- 高质量C++/C编程指南(林锐)
推荐-高质量C++/C编程指南(林锐) 版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐 2001-7-1至 2001-7-18 林锐起草 V 1.0 正式文件 林锐 20 ...
- 物联网操作系统HelloX应用编程指南
HelloX操作系统应用编程指南 HelloX应用开发概述 可以通过三种方式,在HelloX操作系统基础上开发应用: 1. 以内部命令方式实现应用,直接编译链接到HelloX的内核she ...
- JDK 高性能编程之容器
高性能编程在对不同场景下对于容器的选择有着非常苛刻的条件,这里记录下前人总结的经验,并对源码进行调试 JDK高性能编程之容器 读书笔记内容部分来源书籍深入理解JVM.互联网等 先放一个类图util,点 ...
随机推荐
- jq demo 点击选中元素左右移动
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- springcloud Eureka学习笔记
最近在学习springcloud,抽空记录下学习笔记;主要记录Eureka的实现过程和高可用性的实现 Eureka是一个服务治理框架,它提供了Eureka Server和Eureka Client两个 ...
- Shell脚本的学习笔记二:字符串
菜鸟教程提供的Shell在线编辑器 Shell 字符串 项目 功能 单引号 原样输出,变量无效.但可用成对单引号嵌套成对单引号输出变量 双引号 定义字符串中附带有变量的命令并且想将其解析后再输出的变量 ...
- centos7 安装python3.6 脚本
shell 脚本自动安装python3 # /bin/bash cd /opt yum groupinstall "Development tools" -y yum -y ins ...
- CSS 实现单、多行文本溢出显示省略号(…)
如果实现单行文本的溢出显示省略号同学们应该都知道用text-overflow:ellipsis属性来,当然还需要加宽度width属来兼容部分浏览. 实现方法: overflow: hidden; te ...
- day 06 字符串和列表的方法
一.整形int 定义方式: age=18 #调用age=int(18)的方法,自动调用 n=int("123") #只能转换纯数字类型 二:浮点型float 定义方式 sal ...
- java中转译符用"\\"的几种特殊字符
在使用split的方法进行分隔时,要对这几种特殊字符进行"\\"分隔 | * ^ : . 1."|" 示例: String[] splitAddress=add ...
- 软件测试_Linux
# Linux## 基础知识### 操作系统* 作为中间人,连接软件和硬件### Linux * 特点 * 免费+安全### 查看日志,定位bug,修改文件,搭建环境## 安装### 装虚拟机 vmw ...
- java服务端的 极光推送
项目中用到了极光推送 下面写下笔记 首先引入jar包 下载地址https://docs.jiguang.cn/jpush/resources/(非maven项目的下载地址) <depend ...
- Mysql组复制之单主模式(一)
环境 系统:CentOS release 6.9 (Final) Mysql:5.7 机器: S1 10.0.0.7 lemon S2 10.0.0.8 lemon2 S3 10.0.0.9 lemo ...