精华内容
下载资源
问答
  • 采用计算任务量大小的方法,解决了在紧嵌套循环自动并行化过程中存在循环并行化的并行粒度确定问题以及循环自动并行化中数据划分的数据访问局部性问题,在多核系统中实现了紧嵌套循环自动并行化时的数据访问局部性方案...
  • 实时多核架构上具有自动并行化功能的彩色Petri网模型
  • 基于JavaCC的C代码自动并行化的设计与实现
  • Loci 框架为数值应用程序提供了一个自动并行化的框架。 应用程序被表示为规则数据库,并且框架生成规则时间表来执行应用程序。
  • SAPFOR(自动并行化系统) SAPFOR是一种软件开发套件,专注于降低手动程序并行化的成本。 它主要用于执行顺序程序的源到源转换,以在异构集群上执行。 SAPFOR存储库旨在收集该项目的其他存储库,从而使下载单独的...
  • Parallax - 分布式多GPU环境下深度学习训练自动并行化的工具
  • 摘要:针对当 前大量遗产代码无法重复利用的问题,设计一种新的编译工具将C的串行代码转换为基于MPI +...实验结果表明,该工具可以较为理想地实现串行代码自动并行化,与手工编写的代码. 在加速比上的误差为8. 2% ~18. 4%。
  • 自动并行化-在多个作业中运行测试文件 测试Booster基础知识: 测试助推器: 安装 gem install semaphore_test_boosters 什么是测试助推器 测试助推器采用您的测试套件,并将测试文件拆分为多个作业。 这使您可以在...
  • numba用户手册 -3.使用自动并行化@jit

    千次阅读 2020-01-13 19:23:20
    3.使用自动并行化@jit 4.性能提升 5.创建ufunc 6.@jitclass 7.@cfunc 8.提前编译代码AOT 9.numba线程 10.调试 使用自动并行化@jit ---------------------------------------------------------------...

     

    numba用户手册

    1.numba基础

    2.@jit

    3.使用自动并行化@jit

    4.性能提升

    5.创建ufunc

    6.@jitclass

    7.@cfunc

    8.提前编译代码AOT

    9.numba线程

    10.调试

    使用自动并行化@jit
    
    
    
    -------------------------------------------------------------------------------------------------------------------------  
    
    2.1.numba会自动并行化代码:
    
     
    
    具有target="parallel"选项Ufuncs和gufuncs 将在多个线程上运行.
    
    该parallel=True选项@jit将尝试优化数组运算和并行运行它们.它还增加了prange()对显式并行化循环的支持.
    
    您还可以自己在多个线程上手动运行计算,并使用该nogil=True选项(请参见释放GIL).
    
    numba还可以使用其CUDA和HSA后端在GPU架构上实现并行执行.
    
    
    -------------------------------------------------------------------------------------------------------------------------  
    
    2.2.说明:
    
    1)仅适用于CPU.与vectorize()或guvectorize()机制相反,后者需要人工来创建并行内核.
    
    2)数组表达式支持所有numba数组运算,numpy数组间,数组与标量间及ufuncs中通用算术函数.
    
    3)当操作数具有匹配大小时支持多维数组.不支持在选定维度上进行归约
    
    4)支持使用的reduce运算符functools在1D numpy数组上指定并行约简,但必须使用初始值参数
    
    5)parallel=True时prange代替 range指定循环可并行化.要求确保循环除了支持的缩减以外没有交叉迭代依赖项.
    
    6)利用并行硬件唯一要求是设置并行选项jit(),而无需修改函数.等效并行实现guvectorize()将需进行大范围的更改
    
    7)循环体内只能用+=,-= ,*=,和/=.
    
    -------------------------------------------------------------------------------------------------------------------------  
    
    
    # 实例1:
    
    from numba import njit, prange
    
    
    @njit(parallel=True)                          #并行循环
    
    def prange_test(A):
    
        s = 0
    
        for i in prange(A.shape[0]):           #无parallel=True,prange语句相当于range
    
            s += A[i]
    
        return s
    
    -------------------------------------------------------------------------------------------------------------------------   
    
    
    # 实例2:
    
    @njit(parallel=True)                          #二维数组上的乘积约简
    
    def two_d_array_reduction_prod(n):
    
        size = (13, 17)
    
        result = 2 * np.ones(size, np.int_)
    
        tmp = 2 * np.ones_like(result)
    
    
        for i in prange(n):
    
            result *= tmp
    
    
        return result
    
    -------------------------------------------------------------------------------------------------------------------------  
    
    # 实例3.1:
    
    # 如切片或索引指定元素同时由多个并行线程写入,则在简化为数组的切片或元素时应格外小心.
    
    # 编译器可能不会检测到这种情况,会出现竞争状况.
    
    
    @njit(parallel=True)
    
    def prange_wrong_result(x):             #并行for循环竞争条件导致错误的返回值
    
        n = x.shape[0]
    
        y = np.zeros(4)
    
        for i in prange(n):                          #从循环不同并行迭代中累积到同一个元素‘y’中,导致一个竞赛条件
    
            y[:] += x[i]
    
    
        return y
    
    
    # 实例3.2:明确指定了累计元素:
    
    @njit(parallel=True)
    
    def prange_wrong_result(x):
    
        n = x.shape[0]
    
        y = np.zeros(4)
    
        for i in prange(n):                          #从循环的不同并行迭代中累积到同一个元素‘y’中,导致一个竞赛条件
    
            y[i % 4] += x[i]
    
    
        return y
    
    
    # 实例3.3:执行整个数组归约可以:
    
    @njit(parallel=True)
    
    def prange_ok_result_whole_arr(x):
    
        n = x.shape[0]
    
        y = np.zeros(4)
    
        for i in prange(n):
    
            y += x[i]
    
        return y
    
    
    # 实例3.4:就像在并行归约循环之外创建切片参考一样:
    
    @njit(parallel=True)
    
    def prange_ok_result_outer_slice(x):
    
        n = x.shape[0]
    
        y = np.zeros(4)
    
        z = y[:]
    
        for i in prange(n):
    
            z += x[i]
    
        return y
    
    -------------------------------------------------------------------------------------------------------------------------  
    
    # 实例4:并行化Logistic回归:
    
    
    @numba.jit(nopython=True, parallel=True)
    
    def logistic_regression(Y, X, w, iterations):
    
        for i in range(iterations):
    
            w -= np.dot(((1.0 / (1.0 + np.exp(-Y * np.dot(X, w))) - 1.0) * Y), X)
    
        return w
    
    -------------------------------------------------------------------------------------------------------------------------  
    

     

    展开全文
  • BEMAP(用于自动并行器的BEnchMarks)是用于衡量自动并行器性能的基准。 本项目涵盖的所有OpenCL代码基准测试都是与手动调试一起逐步完成的。 使用全面的用户界面和帮助选项详细测量每个调整步骤的执行时间。 每个...
  • ModelingToolkit.jl:Julia中用于自动并行化科学机器学习(SciML)的建模框架。 用于集成符号的计算机代数系统,用于物理知识的机器学习和微分方程的自动转换
  • #资源达人分享计划#
  • pelagia:Surparallel Open Source开发的自动并行化(无锁多线程)工具.Pelagia是嵌入式键值数据库,在ANSI C上实现了小型,快速,高可靠性
  • 同样,上面的例子,还可以很容易的提出一个问题,既然自动并行化会生成OpenMP的指令,那么如果在代码中加入了OpenMP的相关设置线程数量的函数,是否会影响自动并行化的线程数呢,或者说,自动并行化生成多少个线程是...

    参考手册:

    http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011Update/compiler_c/index.htm


    说明:本系列文章为个人笔记,如有不正确之处,请参考官方相关文档,如果错误发现,我会尽量更新修改。另外,以下内容不保证对于所有版本的编译器都正确,编译器的实现也可能有一些变化之处,具体参考官方文档。


    更多说明请参考http://blog.csdn.net/gengshenghong/article/details/7034748中补充说明部分。


    (1) 什么是自动并行化

    Intel编译器的自动并行化功能可以自动的将串行程序的一部分转换为线程化代码。进行自动向量化主要包括的步骤有,找到有良好的工作共享(worksharing)的候选循环;对循环进行数据流(dataflow)分析,确认并行执行可以得到正确结果;使用OpenMP指令生成线程化代码

    说明:由于是使用OpenMP指令生成线程化代码的,所以,自然适用于多核或多处理器的共享内存系统。

    另外,自动并行化分析器会分析循环的数据流,只会给在并行情况下能安全并高效的执行的代码生成多线程代码。

    (2)自动并行化的选项

    /Qparallel:允许编译器进行自动并行化

    /Qpar-reportn:n为0、1、2、3,输出自动并行化的报告

    说明:/Qparallel必须在使用O2/3选项下有效,Od/O1下会被忽略。

    默认情况下,不会输出自动并行化报告,在命令行下编译,自动并行化报告输出到stdout中。

    (3)简单的例子:

    // file: test0.cpp
    // icl test0.cpp /Qparallel /Qpar-report3
    #include <stdio.h>
    
    #define N	1000000
    int main()
    {
    	int a[N];
    	
    	int i = 0;
    	for(i = 0;i < N; i++)
    	{
    		a[i] = i;
    	}
    	
    	printf("%d\n",a[N/2]);		// Must add this, or, O2 may optimize above code.
    	
    	return 0;
    }
    说明:这里的最后一个printf是必须的,总之,要“引用”一下数组a,否则,由于O2选项的优化,上面的循环可能都被优化掉了,因为不printf的话,这个循环被认为没有意义。

    通过修改不同的N,分析生成的自动并行化报告。对于上面的代码,会得到类似下面的报告:

    C:\tempLab\auto_para\test.cpp(11): (col. 2) remark: LOOP WAS AUTO-PARALLELIZED.
    修改N为100,重新编译,得到报告如下:

    C:\tempLab\auto_para\test.cpp(11): (col. 2) remark: loop was not parallelized: insufficient computational work.
    可见循环并没有被并行化,提示说计算任务不充分,这是由于循环太小,不适合进行线程化,这也是编译器“智能化”的表现。

    (4)由上面的例子想到的问题

    问题一:什么样的计算是充分的计算任务呢?

    在运行完上面的例子之后,一个很容易想到的问题是:什么是"充分"的计算任务,也就是说,上面的程序,在N多大的时候才会进行自动向量化?

    经过我手动修改N,在我的机器上,N达到3750及以上就一定会被并行化,否则就不会.如果修改代码,比如增加另一个同样的数据b,在循环中添加b[i] = i,会发现这个能进行自动并行化的N会减小,经过测试,在我的机器上,发现N的临界值为1875,为上面的3750的一半(代码如下)。

    // file: test1.cpp
    // icl test1.cpp /Qparallel /Qpar-report3
    #include <stdio.h>
    
    #define N	1875
    int main()
    {
    	int a[N];
    	int b[N];
    	
    	int i = 0;
    	for(i = 0;i < N; i++)
    	{
    		a[i] = i;
    		b[i] = i;
    	}
    	
    	printf("%d\n",a[N/2]);		// Must add this, or, O2 may optimize above code.
    	printf("%d\n",b[N/2]);
    	
    	return 0;
    }
    总结: 个人认为,编译器会对循环中的计算任务进行分析,显然,这里的分析是静态分析,不需要运行时分析的,所以说,对于一个固定的循环代码,这个能进行自动并行化的“临界值”是一个固定值,编译器会根据循环中的任务复杂程度,来决定这个“临界值”。至于如何决定的,不得而知。理论上猜测,应该是根据处理器以及数目等有关,稍微测试了一下,发现处理器数目并没有影响。(PS:如果能找到相关的说明,就更新这里的描述,这里只是个人根据自己的理解猜测的。)总之,这个对于使用自动并行化并没有影响。

    问题二:自动并行化会生成多少个线程?

    同样,上面的例子,还可以很容易的提出一个问题,既然自动并行化会生成OpenMP的指令,那么如果在代码中加入了OpenMP的相关设置线程数量的函数,是否会影响自动并行化的线程数呢,或者说,自动并行化生成多少个线程是如何决定的?

    在上面的代码中,加入omp_set_num_threads(10);来设置线程数量,通过设置不同的值,分别使用VTune进行并行分析,发现,实际运行的时候,自动并行化的区域,生成的线程数目(OpenMP线程)是和omp_set_num_threads等函数有关系的。

    总结:

    这里的两个问题应该是很容易想到的问题,当然,这两个问题只需要有一个基本理解即可,对于我们使用来说,并不需要真正的去关注编译器是如何来决定多大的计算任务会被并行化以及一段代码最终等价的OpenMP代码是如何的,而且,自动并行化还可能和编译器的其它选项相关联的,下面会介绍一部分。

    (5)同时使用OpenMP和自动并行化

    如果代码中使用了OpenMP进行多线程编程,那么能否使用自动并行化功能呢,或者说,两者一起用的效果会如何?

    首先的是,上面已经说明了,自动并行化的循环区域生成的线程数目和OpenMP的线程环境是有关的。

    然后的问题是,如果是下面的代码编译器会如何处理呢?

    // file: test2.cpp
    // icl test2.cpp /Qparallel /Qpar-report3 /Qopenmp
    #include <stdio.h>
    
    #define N	100000
    int main()
    {
    	int a[N];
    	
    	int i = 0;
    #pragma omp parallel for
    	for(i = 0;i < N; i++)
    	{
    		a[i] = i;
    	}
    	
    	printf("%d\n",a[N/2]);		// Must add this, or, O2 may optimize above code.
    	
    	return 0;
    }
    上面的代码很容易理解,编译后,得到的自动并行化报告如下:

    C:\tempLab\auto_para\test.cpp(12): (col. 2) remark: loop was not parallelized: insufficient computational work.
    可见,上面的循环在使用了OpenMP指令之后不会再次被自动并行化,当然,这也是必然的结果。

    (6)关于自动并行化的处理器相关性

    由于是自动并行化,生成OpenMP线程化代码,所以在Intel处理器和非Intel处理器上都能实现并行化,当然,并行化也可能会其它选项影响,不同的选项生成的代码不一样,也可能会影响自动并行分析器的结果。

    (7)自动并行化和自动向量化

    首先,自动向量化是DLP范畴的,自动并行化是TLP范畴的。在代码中,常见的循环可能是多层循环,而不是都是一层循环,那么Intel编译器的自动并行化是如何处理多层循环的呢?用下面的双层循环来说明。

    // file: test3.cpp
    // icl test3.cpp /Qparallel /Qpar-report3 /Qvec-report3
    #include <stdio.h>
    
    #define N	1000
    int main()
    {
    	int a[N][N];
    	
    	int i = 0;
    	int j = 0;
    	
    	for(i = 0;i < N; i++)
    	{
    		for(j = 0;j < N; j++)
    			a[i][j] = i*j;
    	}
    	
    	printf("%d\n",a[N/2][N/2]);		// Must add this, or, O2 may optimize above code.
    	
    	return 0;
    }
    
    对于上面的代码,编译后得到报告(说明,选项中/Qvec-report3用于输出自动向量化报告,而且O2下自动向量化是默认打开的,关于自动向量化的选项,不在此讨论)如下:

    C:\tempLab\auto_para\test.cpp(13): (col. 2) remark: LOOP WAS AUTO-PARALLELIZED.
    C:\tempLab\auto_para\test.cpp(15): (col. 3) remark: loop was not parallelized: insufficient inner loop.
    C:\tempLab\auto_para\test.cpp(15): (col. 3) remark: LOOP WAS VECTORIZED.
    C:\tempLab\auto_para\test.cpp(13): (col. 2) remark: loop was not vectorized: not inner loop.
    C:\tempLab\auto_para\test.cpp(16): (col. 4) remark: loop was not vectorized: subscript too complex.
    C:\tempLab\auto_para\test.cpp(13): (col. 2) remark: loop was not vectorized: not inner loop.
    可以看到,其中,外层循环被自动并行化了,而内层循环并没有被自动并行化,内层循环被会自动向量化。即使添加选项/Qvec-来禁止自动向量化,编译器也不会对内层循环进行并行化。

    总结:自动向量化一般会针对内层循环进行向量化,自动并行化一般会针对外层循环进行自动并行化。编译器的这两个选项,可以综合使用,从而使得程序尽量优化。

    (8)自动向量化和KMP_STACKSIZE环境变量

    KMP_STACKSIZE环境变量是Intel编译器中OpenMP程序的扩展,用于设置OpenMP的线程的私有堆栈的大小(可参考http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/cpp/lin/optaps/common/optaps_par_var.htm查看OpenMP环境变量)。

    使用/Qparallel选项的时候,可能需要为KMP_STACKSIZE设置一个合适的大小,从而允许并行化。再次看到,自动向量化和OpenMP的相关环境是有关的,这里就不测试这个环境变量可能带来的效果了。

    (9)和自动向量化相关的pragma扩展

    1. #pragma parallel和#pragma noparallel

    这两个选项分别用于在代码中禁止和允许部分循环的自动并行化,要注意,其有效的前提是使用了/Qparallel允许编译器进行自动并行化,否则,程序是肯定不会自动并行化的。另外,这两个指令后面必须紧接一个循环,且只会紧接的循环设置有效。如下面的例子:

    // icl test4.cpp /Qparallel /Qpar-report3
    #include <stdio.h>
    
    #define N	100000
    int main()
    {
    	int a[N];
    	
    	int i = 0;
    	
    	#pragma noparallel
    	for(i = 0;i < N; i++)
    	{
    		a[i] = i;
    	}
    	
    	#pragma parallel
    	for(i = 0;i < N; i++)
    	{
    		a[i] = i;
    	}
    	
    	printf("%d\n",a[N/2]);		// Must add this, or, O2 may optimize above code.
    	
    	return 0;
    }
    第一个循环不会被自动并行化,第二个循环会被自动并行化,当然,第二个循环的#pragme可以被省略。

    2. #pragma parallel的扩展

    #pragma parallel,这个指令只是告诉编译器忽略可能存在的会阻止进行自动并行化的数据依赖、性能降低等,但是,编译器仍然会决定是否真的忽略,如果编译器认为数据依赖或者并行化带来的性能降低等是不可忍受的,还是不会进行自动并行化,这有点类似于c++中inline关键字,只是建议内联,具体实现还是编译器决定。

    #pragma parallel always,这个指令会强制编译器对循环进行并行化,忽略编译器自己的经验。当然,使用此指令的前提是我们确定并行化的结果对我们没有影响,并且要自己为并行化可能带来的性能降低负责。

    #pragma parallel always asert,这个指令会生成错误诊断信息。

    下面的例子可以用于理解#pragma parallel always的效果:

    // file: test5.cpp
    // icl test5.cpp /Qparallel /Qpar-report3
    #include <stdio.h>
    
    #define N	100
    int main()
    {
    	int a[N];
    	
    	int i = 0;
    	
    	#pragma parallel always
    	for(i = 0;i < N; i++)
    	{
    		a[i] = i;
    	}
    	
    	#pragma parallel always
    	for(i = 0;i < N; i++)
    	{
    		printf("%d\n",i);
    	}
    	
    	printf("%d\n",a[N/2]);		// Must add this, or, O2 may optimize above code.
    	
    	return 0;
    }
    上面的两个循环都会被并行化,但是如果去掉always,那么都不会被并行化,因为它们都不符合并行化的条件,其中,第一个循环由于N太小,并行化性能不一定有提升,但是结果正确,第二个循环是由数据依赖的,如果并行化,结果就会不正确,可见,always是强制的并行化,只有在特殊的情况下可能会使用。
    展开全文
  • 自动并行化的实现,前面已经知道,是通过OpenMP指令来实现的,那么,如果更为具体或进一步的说,自动并行化,是通过实现OpenMP的一些概念,比如工作共享构造(worksharing consruct)的,即parallel for指令。...

    参考手册:

    http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011Update/compiler_c/index.htm


    说明:本系列文章为个人笔记,如有不正确之处,请参考官方相关文档,如果错误发现,我会尽量更新修改。另外,以下内容不保证对于所有版本的编译器都正确,编译器的实现也可能有一些变化之处,具体参考官方文档。


    更多说明请参考http://blog.csdn.net/gengshenghong/article/details/7034748中补充说明部分。


    Summary:

    前面介绍了使用自动并行化相关的一些基本的选项和相关的理解,这一部分继续理解自动并行化,从编程的角度来分析要注意的一些基本问题。

    (1) 自动并行化数据流

    对于自动并行化的处理,编译器执行下面步骤(为了避免我自己翻译导致不太正确,下面的内容直接来自于Intel编译器文档原文):

    1.Data flow analysis: Computing the flow of data through the program.

    2.Loop classification: Determining loop candidates for parallelization based on correctness and efficiency, as shown by threshold analysis.
    3.Dependency analysis: Computing the dependency analysis for references in each loop nest.
    4.High-level parallelization: Analyzing dependency graph to determine loops which can execute in parallel, and computing run-time dependency.
    5.Data partitioning: Examining data reference and partition based on the following types of access: SHARED, PRIVATE, and FIRSTPRIVATE.
    6.Multithreaded code generation: Modifying loop parameters, generating entry/exit per threaded task, and generating calls to parallel run-time routines for thread creation and synchronization.

    大概就是数据流分析、循环分类、依赖分析、高阶并行化、数据划分、线程化代码生成等。当然,这个流程只需要了解即可。

    (2) 再说什么样的代码可以被并行化

    前面的内容已经分析过"什么样的计算是充分的计算任务呢",这里再次从理论上分析什么样的代码可能被并行化。

    1. 自动并行化的实现

    自动并行化的实现,前面已经知道,是通过OpenMP指令来实现的,那么,如果更为具体或进一步的说,自动并行化,是通过实现OpenMP的一些概念,比如工作共享构造(worksharing consruct)的,即parallel for指令。那么,自然,什么样的代码能被并行化,就可能和OpenMP的parallel for类似了。

    2. 什么样的代码可以被并行化

    类似于parallel for指令,一个循环可以被有效的并行化,需要满足以下基本条件:

    A、循环迭代次数是编译时可数的。这是和parallel for一样的要求,因为要静态的进行线程的调度分配等,循环迭代次数在编译时就应该是可以确定的。

    B、没有flow(read after write), output(write after write) anti(write after read)等loop-carried数据依赖。loop-carried数据依赖发生在循环的不同迭代引用同一个内存位置。

    3. 编程指南

    根据上面的有效并行化的条件,自然对应了两条基本的编程指南:

    A、尽量暴露循环数量,特别是使用常量,并保存循环变量为本地变量。

    B、避免将结构体放到循环体内部,可能导致编译器认为有数据依赖,比如过程调用、含有歧义的非直接引用、全局引用等。

    PS:这个应该是跟编译器的"智能化"程度有关的,所以,在此一时我也没想到什么好的例子能证明这两点,不过这些都不用太担心,因为Intel编译器还有有一个很好的功能就是能帮忙检测代码,帮助我们进行自动向量化和自动并行化,下一部分讨论这个功能。:)

    (3)和自动并行化有关的语言扩展(attributes)
    参考:
    win:
    __declspec(concurrency_safe(cost(cycles) | profitable))
    Lin:
    __attribute__(concurrency_safe(cost(cycles) | profitable))
    用于指导编译器并行化更多循环和直线型代码(straight-line code).
    concurrency_safe属性告诉编译器在多个调用被注释的函数或该函数和程序其他语句同时执行时没有副作用和非法访问或不适当的同步内存访问(翻译得有点烂?那就参考上面的链接原文吧!)。cycles指定的是编译器对注释的函数进行并行化效益分析的时候的执行周期。profitable表示包含对注释函数的调用的循环或块在并行化时候都是可以受益的。cycles的最大值是2^16-1,如果周期数大于此值,就是用profitable语句。
    个人理解,这个属性用于告诉编译器,其计算任务需要花费的“时间”消耗。cycles用于比较短的时间,profitable相当于是一个比较大的时间吧。这是我根据文档的例子理解的。下面是我的测试代码:
    // icl test0.cpp /Qparallel /Qpar-report3
    #include <stdio.h>
    
    #define N	1000000
    
    __declspec(concurrency_safe(cost(10)))
    __declspec(noinline)
    void foo(int* a, int i)
    {
    	a[i] = i;
    }
    
    int main()
    {
    	int a[N];
    	int i = 0;
    	
    	#pragma parallel
    	for(i = 0;i < N; i++)
    	{
    		foo(a,i);
    	}
    	
    	printf("%d\n",a[N/2]);		// Must add this, or, O2 may optimize above code.
    	
    	return 0;
    }
    下面是我根据测试得到的一些说明或问题或结论:
    1. 说明:上面之所以用noinline指定函数不内联,是为了模拟函数调用,因为编译器在O2下会自动进行判断和内联,上面的函数过于简单,不加noinline的时候,函数肯定会被内联的,这时候,concurrency_safe的cost值对内联后的代码不会有什么影响,这时候,是否进行并行化完全由N的大小决定。
    2. 问题:在测试的时候,发现一个问题是,在使用了noinline的情况下,也就是foo当成函数处理,这时候,N不管多大,都会提示"remark: loop was not parallelized: insufficient computational work.",即计算任务不充分,个人的理解,这里调用函数也应该和不调用是一样的效果,因为“计算任务”应该是取决于N的大小的,总之,这是一个问题,可能是某些地方我没有理解到,或者编译器有自己的“经验”任务对于函数调用,不能只考虑N。当然,从某种程度上来讲,也就是这个问题,才带来了concurrency_safe属性吧。
    3. 结论:就针对上面的程序,实际测试的结果是,for循环是否并行化,不是取决于N,也不是取决于cost的值,而是两者的一个结合。当然,首先的是,N和cost都超过一定的值才会进行并行化。另外,当N比较大的时候,进行并行化的cost的临界值会相对较小,当N比较小的时候,进行并行化的cost的临界值会比较大。
    说明:关于这个属性的更多理解,请查阅相关资料,这里只是一个基本的测试,可能不能反应其工作原理,作为一个基础,了解即可。
    展开全文
  • 它基于多个组件,包括源到源编译器框架 (科学程序的程序间并行化,地球上仍然存在的最古老的研究编译器),由 、 和。 Par4All 使用一个命令行自动将 C 和 Fortran 顺序程序转换为并行程序。 它将在多核和众核...
  • 前面了解了Intel编译器的自动并行化的一些选项,下面要介绍的是另一个功能,即向导自动并行化(guided auto palatalization, GAP)。简单的理解,向导自动化就是编译器根据代码编译后,告诉用户一些建议来对代码进行...
    参考手册:
    

    http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011Update/compiler_c/index.htm


    说明:本系列文章为个人笔记,如有不正确之处,请参考官方相关文档,如果错误发现,我会尽量更新修改。另外,以下内容不保证对于所有版本的编译器都正确,编译器的实现也可能有一些变化之处,具体参考官方文档。


    更多说明请参考http://blog.csdn.net/gengshenghong/article/details/7034748中补充说明部分。


    Summary:

    前面了解了Intel编译器的自动并行化的一些选项,下面要介绍的是另一个功能,即向导自动并行化(guided auto palatalization, GAP)。简单的理解,向导自动化就是编译器根据代码编译后,告诉用户一些建议来对代码进行优化。

    (1) GAP基础

    GAP是向导自动并行化,可以理解为一个工具,对代码给出建议,从而根据建议来优化代码。

    1. GAP的“建议”是不是都是自动并行化的建议?

    并行化,包括很多方面,前面一部分的/Qparallel的自动并行化主要是针对线程级并行,那么这里的GAP是不是都是和/Qparallel有关的建议呢?答案是否定的。GAP的建议目前主要包括auto-parallel和auto-vec和data transformation三个方面,即自动并行化和自动向量化和数据转换

    2. GAP如何使用?

    只需要在编译的时候,使用选项/Qguide即可。使用/Qguide有效的前提是使用了O2/3等选项。使用了/Qguide选项后,编译器并不会真的去"编译"代码,而是分析代码后给出优化建议,也就是说,使用了/Qguide后,GAP运行过程中不会产生.obj文件或可执行文件。

    3. 建议类型

    GAP给出的一些建议消息主要包括以下三种:

    代码修改建议:即告诉用户哪些地方的代码可以修改后,能提升性能或利于编译器进行优化。建议为指针参数增加restrict关键字消除歧义,建议在循环体开始初始化局部变量等。一般而言,这些代码建议都是为了让编译器更确定能进行优化,比如restrict消除歧义等,当然,这些建议并不是一定需要接受。比如有些指针参数可能是不能使用restrict的,根据用户需要来决定。
    使用pragmas建议:即告诉用户给特定的循环增加pragmas注释,从而辅助编译器优化。
    增加编译选项建议:即告诉用户增加一些优化选项,来进行优化。

    总结:GAP的建议,都是为了更好的帮助编译器优化。而且,GAP给出的建议也是和使用的选项相关的,比如,最开始GAP可能只给出一条建议,让用户考虑增加/Qparallel选项,增加后,再次编译,会给出更多建议等。

    (2) GAP选项

    /Qguide[:n]:使用GAP,其中n表示级,取值为1到4。默认级别为4。级别越高,给出的建议考虑的内容越多。

    /Qguide-par[:n]:只处理自动并行化(auto-parallelization)相关的建议。说明:必须使用/Qparallel选项。

    /Qguide-vec[:n]:只处理自动向量化(auto-vectorization)相关的建议。

    /Qguide-data-trans[:n]:只处理和数据转换(data transformation)相关的建议。

    说明:上面的n都是可选的,取值从1到4.

    默认情况下,GAP的消息输出到stderr中。如果要将消息输出到文件,可以使用如下选项(当然,这两个选项都是在使用上面的GAP的选项才有效):

    /Qguide-file[:file_name]
    /Qguide-file-append[:file_name]

    (3)针对指定的热点进行分析

    GAP还有一个功能是能针对已知的热点代码进行分析。所谓的“热点”,就是程序中耗时的部分。

    选项:

    /Qguide-opts:string

    说明:其中string,需要根据一定的格式书写,其表示的含义可能是一个文件、一个函数等,用于告诉GAP需要分析的代码部分。当然,/Qguide-opts选项也需要结合上面的GAP选项一起使用。更多具体信息,参考官方文档。

    (3) GAP的消息

    在官方文档上,可以查到相关的GAP信息的说明。那么,GAP的建议消息是不是都需要接受呢?这是不一定的。需要用户根据代码判断,有些消息只是用于告诉用户修改后可以得到优化,但是修改后的正确性用户必须自己保证(特别是有些代码是由于存在歧义,GAP会提示用户消除歧义),那么,如果用户希望GAP不提示某一个诊断信息,如何实现?可以使用选项/Qdiag-disable:list,其中list列举要禁用的消息的ID即可。


    展开全文
  • 前面了解了Intel编译器的自动并行化相关的编程要注意的地方等,也简单的了解了自动并行化相关的基本选项,这里对这些内容做一个总结,也算是对自动并行化部分的一个结束。 (1)自动并行化选项 1. /Qparallel:...
  • 在理想情况下,编译器使用自动并行化能够管理一切事务,使用OpenMP指令的一个优点是将并行性和算法分离,阅读代码时候无需考虑并行化是如何实现的。当然for循环是可以并行化处理的天然材料,满足一些约束的for循环...
  • 基于云计算的并行化自动测试系统设计.pdf
  • 行业分类-物理装置-一种并行化SQL自动生成方法.zip
  • 支持程序自动并行化的本质是判定相互之间不存在相关的代码块,因此如何精确地获取包括控制流图和数据流图在内的程序运行时行为成为程序自动并行化的基础。将虚拟机技术运用于并行程序优化领域,设计了基于虚拟机的...
  • CPF是一种编译器基础结构,可自动并行化顺序C / C ++程序,以在共享内存多核系统上有效运行。 刊物 这项工作在Apostolakis等人的ASPLOS '20论文中进行了描述。 标题为“透视:推测性自动并行化的明智方法”( , )...
  • 基于设计模式的思想,设计并实现了两种并行编程框架,用户可以直接调用 框架提供的高级应用程序接口,就可以自动的完成数据的划分和任务的自动并行 执行。基于数据并行计算提出了一种基于阵列数据并行的FJRR并行...
  • AlphaSQL为SQL文件集和集成的Type / Scheme Checker提供自动并行化功能,以消除数据仓库中的语法,类型和架构错误。 特征 您可以通过快速介绍AlphaSQL。 在Docker上使用我们的AlphaSQL;) 对于本地使用,二进制...
  • 高精度三相电能表的自动化并行校检方法.pdf
  • 目前GIS基础算法并行化成为高性能GIS进一步深入的前提, 作为GIS空间分析基础算法的重点, 有必要对多边形构建提出一种自动并行算法。为此, 提出基于图模型的多边形自动并行构建算法。该算法根据图模型中有向闭合环的...
  • 多无线通信终端并行自动化射频测试系统开发与应用.pdf
  • 本文的意图是通过一个新的视角颠覆传统理念上的串行自动化测试方式,向读者详细介绍了利用STAF以及Selenium实现的并行式的自动化测试框架,以及为整个项目所带来的优势。  Agile中的自动化测试  Agile是一种以人为...
  • 深度学习及并行化实现概述

    千次阅读 2018-02-08 21:25:50
    深度学习及并行化实现概述摘要: 深度学习可以完成需要高度抽象特征的人工智能任务,如语音识别、图像识别和检索、自然语言理解等。深层模型是包含多个隐藏层的人工神经网络,多层非线性结构使其具备强大的特征表达...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 239,814
精华内容 95,925
关键字:

自动并行化