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

● 代码,单线程

 #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. 手把手教你用git

    一.如何安装git 下载地址: https://git-scm.com/download/win 根据自己的电脑选择是32位的还是64位的.下载完后直接运行,之后一直next就好了.安装成功后,会有这 ...

  2. 在Power BI报表和仪表板中显示刷新日期\时间

    有人最近问我:“如何在报告和仪表板中显示最后刷新数据的日期和时间?”这里有两个简单的技巧在这分享下,也许可以帮助到你. 显示上次刷新日期\时间 要想显示刷新的日期和时间,我们需要在模型本身中存储时间刷 ...

  3. Js/对数组的认识。

    1.是对数组的声明:   var auditTaskIds = []; 我一般的写法.   var auditTaskIds1 = [];  2.向数组中添加元素:   auditTaskIds.pu ...

  4. 使用FileZilla连接时超时,无法连接到服务器

    更改一下加密方式,就是不用TLS,用相对不安全方式的(可选项)  腾讯云就是这样的,

  5. Qt对`vtable的未定义引用

    错误描述:Qt在linux系统编译时,遇到一个错误大致如下形式 在 xxxxx函数中 对‘vtable for xxxxx未定义的引用 网上找了很多,各种情况都有,大多数是虚函数未实现导致的, 但也有 ...

  6. python3 访问百度返回压缩格式

    import urllib, urllib.request, urllib.parse import random import zlib import re import os, time Save ...

  7. 阅读 video in to axi4-stream v4.0 笔记

    阅读 video in to axi4-stream v4.0 笔记 axi4 stream里面只传输的有效数据. 引用: 使能了video timing controller core 的所用信号, ...

  8. Delphi2009之TImage

    TPngImage原来是SourceFroge上的一个开源项目,现在突然消失了,为什么呢?Nick 在他的博客上写到:TPNGImage被CodeGear/Embarcadero收购了,现在直接就是D ...

  9. 【C++】vector用法详解

    转自:https://blog.csdn.net/fanyun_01/article/details/56842637#commentBox 一.简介 C++ vector类为内置数组提供了一种替代表 ...

  10. globals和locals的区别

    Python的两个内置函数,locals 和globals,它们提供了基于字典的访问局部和全局变量的方式. 1.locals()是只读的.globals()不是.这里说的只读,是值对于原有变量的只读. ...