小编mat*_*mul的帖子

复制BLAS矩阵乘法性能:我能匹配吗?

背景

如果您一直关注我的帖子,我试图复制Kazushige Goto关于方阵乘法的开创性论文中的结果C = AB.我在这里可以找到关于这个主题的最后一篇文章.在我的代码版本中,我遵循Goto的内存分层和打包策略2x8以及C使用128位SSE3内在函数的内核计算块.我的CPU是i5-540M,超线程关闭.有关我的硬件的其他信息可以在另一篇文章中找到,并在下面重复.

我的硬件

我的CPU是Intel i5 - 540M.您可以在cpu-world.com上找到相关的CPUID信息.微体系结构是Nehalem(westmere),因此理论上每循环每个核心可以计算4个双精度触发器.我将只使用一个核心(没有OpenMP),所以对于超线程关闭和4步Intel Turbo Boost,我应该会看到一个高峰( 2.533 Ghz + 4*0.133 Ghz ) * ( 4 DP flops/core/cycle ) * ( 1 core ) = 12.27 DP Gflops.作为参考,两个核心都运行在峰值,英特尔Turbo Boost提供了两步加速,我应该获得理论峰值22.4 DP Gflops.

我的软件

Windows7 64位,但MinGW/GCC 32位由于我的电脑限制.

这次有什么新鲜事?

  • 我计算2x4C.这提供了更好的性能,并且与Goto所说的一致(一半寄存器用于计算C).我试过很多大小:1x8,2x8,2x4,4x2,2x2,4x4.
  • 我的内核是手工编码的x86程序集,我尽我所能进行了优化(与Goto编写的一些内核相匹配),这比SIMD提供了相当大的性能提升.此代码在内核内部展开8次(为方便起见定义为宏),从我尝试的其他展开策略中获得最佳性能.
  • 我使用Windows性能计数器来计算代码的时间,而不是clock().
  • 我独立于总代码计算内核,看看我的手工编码程序集的效果如何.
  • 我报告了一些试验的最佳结果,而不是试验的平均结果. …

c optimization assembly blas

21
推荐指数
1
解决办法
1103
查看次数

不能超过50%.矩阵乘法的理论性能

问题

我正在学习HPC和代码优化.我试图在Goto的开创性矩阵乘法论文(http://www.cs.utexas.edu/users/pingali/CS378/2008sp/papers/gotoPaper.pdf)中复制结果.尽管我付出了最大努力,但我无法超过理论CPU最高性能的50%.

背景

请参阅此处的相关问题(优化的2x2矩阵乘法:慢速装配与快速SIMD),包括有关我的硬件的信息

我尝试过的

这篇相关论文(http://www.cs.utexas.edu/users/flame/pubs/blis3_ipdps14.pdf)很好地描述了Goto的算法结构.我在下面提供了我的源代码.

我的问题

我要求一般帮助.我一直在研究这个问题太久了,已经尝试了很多不同的算法,内联汇编,各种尺寸的内核(2x2,4x4,2x8,...,mxn m和n大),但我似乎无法打破50%CPU Gflops.这纯粹是出于教育目的,而不是作业.

源代码

希望是可以理解的.如果没有请问.我设置了宏结构(for循环),如上面第2篇文章中所述.我按照两篇论文中的讨论打包矩阵,并在图11中以图形方式显示(http://www.cs.utexas.edu/users/flame/pubs/BLISTOMSrev2.pdf).我的内核计算2x8块,因为这似乎是Nehalem架构的最佳计算(参见GotoBLAS源代码 - 内核).内核基于计算排名1更新的概念,如此处所述(http://code.google.com/p/blis/source/browse/config/template/kernels/3/bli_gemm_opt_mxn.c)

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <x86intrin.h>
#include <math.h>
#include <omp.h>
#include <stdint.h>


// define some prefetch functions
#define PREFETCHNTA(addr,nrOfBytesAhead) \
        _mm_prefetch(((char *)(addr))+nrOfBytesAhead,_MM_HINT_NTA)

#define PREFETCHT0(addr,nrOfBytesAhead) \
        _mm_prefetch(((char *)(addr))+nrOfBytesAhead,_MM_HINT_T0)

#define PREFETCHT1(addr,nrOfBytesAhead) \
        _mm_prefetch(((char *)(addr))+nrOfBytesAhead,_MM_HINT_T1)

#define PREFETCHT2(addr,nrOfBytesAhead) \
        _mm_prefetch(((char *)(addr))+nrOfBytesAhead,_MM_HINT_T2)

// define a min function
#ifndef min
    #define min( a, b ) ( …
Run Code Online (Sandbox Code Playgroud)

c optimization sse matrix openmp

18
推荐指数
1
解决办法
698
查看次数

如何使用Dot产品获得峰值CPU性能?

问题

我一直在研究HPC,特别是使用矩阵乘法作为我的项目(参见我在配置文件中的其他帖子).我在那些方面取得了不错的成绩,但还不够好.我退后一步看看我能用点积计算做得多好.

点积与矩阵乘法

点积更简单,可以让我测试HPC概念,而无需处理打包和其他相关问题.缓存阻塞仍然是一个问题,这是我的第二个问题.

算法

乘以n相应的元件以两种double阵列AB与它们求和.一个double组装点积仅仅是一系列的movapd,mulpd,addpd.以一种聪明的方式展开和排列,可以使用movapd/ mulpd/ addpd在不同xmm寄存器上操作的组,因此是独立的,优化流水线操作.当然,事实证明,这与我的CPU无序执行无关.另请注意,重新安排需要剥离最后一次迭代.

其他假设

我不是在写一般点产品的代码.代码是针对特定尺寸的,我不处理边缘情况.这只是为了测试HPC概念并查看我可以获得的CPU使用类型.

结果

编译gcc -std=c99 -O2 -m32 -mincoming-stack-boundary=2 -msse3 -mfpmath=sse,387 -masm=intel.我和平时不同的电脑.这台计算机有一个i5 540m可以2.8 GHz * 4 FLOPS/cycle/core = 11.2 GFLOPS/s per core在两步英特尔Turbo Boost后获得(两个核心现在都在,所以它只有2步...如果我关掉一个核心,可以进行4步增强).设置为使用一个线程运行时,32位LINPACK大约为9.5 GFLOPS/s.

       N   Total Gflops/s         Residual
     256         5.580521    1.421085e-014
     384         5.734344   -2.842171e-014
     512         5.791168    0.000000e+000
     640         5.821629    0.000000e+000
     768         5.814255    2.842171e-014
     896         5.807132 …
Run Code Online (Sandbox Code Playgroud)

c optimization caching hpc

12
推荐指数
1
解决办法
1589
查看次数

优化的2x2矩阵乘法:慢速装配与快速SIMD

问题

我正在研究高性能矩阵乘法算法,如OpenBLAS或GotoBLAS,我正在尝试重现一些结果.这个问题涉及矩阵乘法算法的内核.具体来说,我正在研究计算C += AB,在我的CPU的峰值速度下,在哪里AB是2x2类型的矩阵double.有两种方法可以做到这一点.一种方法是使用SIMD指令.第二种方法是使用SIMD寄存器直接在汇编代码中编码.

到目前为止我看过的是什么

所有相关论文,课程网页,许多SO Q&As处理主题(太多无法列出),我已经在我的计算机上编译了OpenBLAS,查看了OpenBLAS,GotoBLAS和BLIS源代码,Agner的手册.

硬件

我的CPU是Intel i5 - 540M.您可以在cpu-world.com上找到相关的CPUID信息.微体系结构是Nehalem(westmere),因此理论上每循环每个核心可以计算4个双精度触发器.我将只使用一个核心(没有OpenMP),所以对于超线程关闭和4步Intel Turbo Boost,我应该会看到一个高峰( 2.533 Ghz + 4*0.133 Ghz ) * ( 4 DP flops/core/cycle ) * ( 1 core ) = 12.27 DP Gflops.作为参考,两个核心都运行在峰值,英特尔Turbo Boost提供了两步加速,我应该获得理论峰值22.4 DP Gflops.

建立

我将我的2x2矩阵声明为double并使用随机条目对其进行初始化,如下面的代码片段所示.

srand(time(NULL));
const int n = 2;
double A[n*n];
double B[n*n];
double C[n*n];
double T[n*n];
for(int i = 0; i < n*n; i++){
    A[i] = (double) rand()/RAND_MAX; …
Run Code Online (Sandbox Code Playgroud)

c assembly matrix

8
推荐指数
1
解决办法
1860
查看次数

标签 统计

c ×4

optimization ×3

assembly ×2

matrix ×2

blas ×1

caching ×1

hpc ×1

openmp ×1

sse ×1