▶ 第二章,几个简单的程序

● 代码,单线程

 #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的更多相关文章

  1. Xeon Phi 《协处理器高性能编程指南》随书代码整理 part 1

    ▶ 第三章,逐步优化了一个二维卷积计算的过程 ● 基准代码 #include <stdio.h> #include <stdlib.h> #include <string ...

  2. Xeon Phi 《协处理器高性能编程指南》随书代码整理 part 4

    ▶ 第五章,几个优化 ● 代码 #include <stdio.h> #include <stdlib.h> #include <math.h> #define S ...

  3. Xeon Phi 《协处理器高性能编程指南》随书代码整理 part 2

    ▶ 第四章,逐步优化了一个三维卷积计算的过程 ● 基准代码 #include <stdio.h> #include <stdlib.h> #include <string ...

  4. Xeon Phi 编程备忘

    ▶ 闲鱼的 Xeon Phi 3120A 配办公室的新 Xeon 服务器,记录一下环境安装过程. ● 原本尝试搭 Ubuntu 服务器,参考[https://software.intel.com/en ...

  5. Python猫荐书系列之五:Python高性能编程

    稍微关心编程语言的使用趋势的人都知道,最近几年,国内最火的两种语言非 Python 与 Go 莫属,于是,隔三差五就会有人问:这两种语言谁更厉害/好找工作/高工资…… 对于编程语言的争论,就是猿界的生 ...

  6. 《高性能javascript》一书要点和延伸(上)

    前些天收到了HTML5中国送来的<高性能javascript>一书,便打算将其做为假期消遣,顺便也写篇文章记录下书中一些要点. 个人觉得本书很值得中低级别的前端朋友阅读,会有很多意想不到的 ...

  7. 高质量C++/C编程指南(林锐)

    推荐-高质量C++/C编程指南(林锐) 版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐   2001-7-1至 2001-7-18 林锐起草 V 1.0 正式文件 林锐   20 ...

  8. 物联网操作系统HelloX应用编程指南

    HelloX操作系统应用编程指南 HelloX应用开发概述 可以通过三种方式,在HelloX操作系统基础上开发应用: 1.        以内部命令方式实现应用,直接编译链接到HelloX的内核she ...

  9. JDK 高性能编程之容器

    高性能编程在对不同场景下对于容器的选择有着非常苛刻的条件,这里记录下前人总结的经验,并对源码进行调试 JDK高性能编程之容器 读书笔记内容部分来源书籍深入理解JVM.互联网等 先放一个类图util,点 ...

随机推荐

  1. jq demo 点击选中元素左右移动

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  2. springcloud Eureka学习笔记

    最近在学习springcloud,抽空记录下学习笔记;主要记录Eureka的实现过程和高可用性的实现 Eureka是一个服务治理框架,它提供了Eureka Server和Eureka Client两个 ...

  3. Shell脚本的学习笔记二:字符串

    菜鸟教程提供的Shell在线编辑器 Shell 字符串 项目 功能 单引号 原样输出,变量无效.但可用成对单引号嵌套成对单引号输出变量 双引号 定义字符串中附带有变量的命令并且想将其解析后再输出的变量 ...

  4. centos7 安装python3.6 脚本

    shell 脚本自动安装python3 # /bin/bash cd /opt yum groupinstall "Development tools" -y yum -y ins ...

  5. CSS 实现单、多行文本溢出显示省略号(…)

    如果实现单行文本的溢出显示省略号同学们应该都知道用text-overflow:ellipsis属性来,当然还需要加宽度width属来兼容部分浏览. 实现方法: overflow: hidden; te ...

  6. day 06 字符串和列表的方法

    一.整形int 定义方式: age=18    #调用age=int(18)的方法,自动调用 n=int("123") #只能转换纯数字类型 二:浮点型float 定义方式 sal ...

  7. java中转译符用"\\"的几种特殊字符

    在使用split的方法进行分隔时,要对这几种特殊字符进行"\\"分隔 | * ^ : . 1."|" 示例: String[] splitAddress=add ...

  8. 软件测试_Linux

    # Linux## 基础知识### 操作系统* 作为中间人,连接软件和硬件### Linux * 特点 * 免费+安全### 查看日志,定位bug,修改文件,搭建环境## 安装### 装虚拟机 vmw ...

  9. java服务端的 极光推送

    项目中用到了极光推送  下面写下笔记 首先引入jar包   下载地址https://docs.jiguang.cn/jpush/resources/(非maven项目的下载地址) <depend ...

  10. 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 ...