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

● 代码,单线程

 #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. 原生js手风琴效果

    //js代码 //获取li var list = document.getElementsByTagName("li")[0]; //遍历  排他 for( var i=0;i&l ...

  2. python笔记10-切片(从list或字符串中取几个元素)

    name1 = 'zcl,pyzyz'names = ['zcl','py','zyz'] #切片的意思就是从list里面或者字符串里面取几个元素#切片操作对字符串也是完全适用的 # print(na ...

  3. 阶段01Java基础day17集合框架03

    17.01_集合框架(HashSet存储字符串并遍历) A:Set集合概述及特点 通过API查看即可 B:案例演示 HashSet存储字符串并遍历 HashSet<String> hs = ...

  4. python基础12_匿名_内置函数

    一个二分查找的示例: # 二分查找 示例 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35, 36, ...

  5. .NET并行计算和并发5:多线程编程一般指导性原则

    使用多线程时要考虑以下准则: 不要使用 Thread.Abort 终止其他线程. 对另一个线程调用 Abort 无异于引发该线程的异常,也不知道该线程已处理到哪个位置. 不要使用 Thread.Sus ...

  6. setfacl语法

    1.setfacl的用途setfacl命令可以用来细分linux下的文件权限. chmod命令可以把文件权限分为u,g,o三个组,而setfacl可以对每一个文件或目录设置更精确的文件权限. 换句话说 ...

  7. 二进制安装MySQL数据库

    今天安装的是二进制的mysql包5.7.21的包,在配置文件的时候采了好多坑,左后还是搞定了,来和大家分享一下 二进制msyql5.7.21版本的主从复制安装 新建/picclife目录 mkdir  ...

  8. .net webapi跨域方法整理

    方法一 在Web.Config里面加上了配置信息: <httpProtocol> <customHeaders> <add name="Access-Contr ...

  9. https原理及其中所包含的对称加密、非对称加密、数字证书、数字签名

    声明:本文章已授权公众号Hollis转载,如需转载请标明转载自https://www.cnblogs.com/wutianqi/p/10654245.html(安静的boy) 一.为什么要使用http ...

  10. CXF develop Webserice Tuturial

    1. 修改pom.xml 在Maven中引入CXF 依赖包 1.1 引入CXF依赖包 ,配置Tomcat插件及其它 <project xmlns="http://maven.apach ...