标签: loop-unrolling

如何为编译器提供有关循环运行的最长时间的提示

// if I know that in_x will never be bigger than Max
template <unsigned Max>
void foo(unsigned in_x)
{
    unsigned cap = Max;

    // I can tell the compiler this loop will never run more than log(Max) times
    for (; cap != 0 && in_x != 0; cap >>= 1, in_x >>= 1)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

如上面的代码所示,我的猜测是,如果我只是写

for(; in_x!= 0; in_x >> = 1)

编译器不会展开循环,因为它无法确定最大可能的in_x.

我想知道我是对还是错,如果有更好的方法来处理这些事情.


或者也许问题可以概括为好像可以编写一些代码来告诉编译器一些运行时值的范围,并且这些代码不一定被编译成运行时二进制文件.


真的,与编译器XD战斗

// with MSC
// if no __forceinline here, unrolling is ok, but …
Run Code Online (Sandbox Code Playgroud)

c++ loop-unrolling

5
推荐指数
1
解决办法
250
查看次数

在特殊情况下展开循环循环

因此,我正在尝试优化一些代码。我有一个可变大小的循环功能。但是,为了提高效率,我想将具有1、2和3大小的循环的案例设为完全展开的特殊案例。到目前为止,我的方法是将循环大小声明为const参数,然后定义包装函数,这些包装函数调用主函数,将其递归为const值的文字。我已经包含了一段代码片段,说明了我的想法。

inline void someFunction (const int a)
{
    for (int i=0; i<a; i++)
    {
        // do something with i.
    }
}

void specialCase()
{
    someFunction (3);
}

void generalCase(int a)
{
    someFunction (a);
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是期望我的编译器(GCC)在specialCase内部展开for循环是否合理?我的意思是显然我可以复制-将someFunction的内容粘贴到specialCase中,并用3替换a,但是为了清楚起见,我宁愿只在代码中处理someFunction的一个定义。

c++ gcc loop-unrolling

5
推荐指数
1
解决办法
316
查看次数

在C++中通过固定大小的数组展开循环是否有益?

我想用它std::array来存储N维向量的数据,并为这些向量实现算术运算.我想,既然std::array现在有一个constexpr size()成员函数,我可以使用它来展开算术运算所需的循环.

这是一个最小的例子:

#include <array> 
#include <type_traits>
#include <iostream>
#include <cassert>

template<std::size_t N=0, typename Vector>
void plus_equals(Vector& result, Vector const& input) 
{
    result[N] += input[N]; 

    if constexpr (N + 1 < result.size()) 
        plus_equals<N+1>(result, input); 
}

template<typename INT, size_t N>
class Vector
{
    std::array<INT, N> data_; 

    public: 

        template<typename ... BracketList> 
        Vector(BracketList ... blist)
        :
            data_{std::forward<BracketList>(blist)...}
        {} 

        INT& operator[](std::size_t i)
        {
            return data_[i]; 
        }

        INT operator[](std::size_t i) const 
        {
            return data_[i]; 
        }

        decltype(auto) begin() const 
        { …
Run Code Online (Sandbox Code Playgroud)

c++ optimization loop-unrolling stdarray

5
推荐指数
1
解决办法
298
查看次数

在循环展开时出现"资源不足"错误

当我在内核中将展开从8个循环增加到9个循环时,会出现out of resources错误.

我读了如何诊断由于资源不足导致的CUDA启动失败?参数不匹配和寄存器过度使用可能是一个问题,但这似乎不是这种情况.

我的内核计算n点和m质心之间的距离,并为每个点选择最接近的质心.它适用于8个维度,但不适用于9.当我dimensions=9为距离计算设置和取消注释这两行时,我得到了一个pycuda._driver.LaunchError: cuLaunchGrid failed: launch out of resources.

您怎么看,可能会导致这种行为?还有什么其他的可以导致out of resources*?

我使用的是Quadro FX580.这是最小(ish)的例子.为了展开真正的代码我使用模板.

import numpy as np
from pycuda import driver, compiler, gpuarray, tools
import pycuda.autoinit


## preference
np.random.seed(20)
points = 512
dimensions = 8
nclusters = 1

## init data
data = np.random.randn(points,dimensions).astype(np.float32)
clusters = data[:nclusters]

## init cuda
kernel_code = """

      // the kernel definition 
    __device__ __constant__ float centroids[16384];

    __global__ void …
Run Code Online (Sandbox Code Playgroud)

cuda loop-unrolling pycuda

4
推荐指数
1
解决办法
1233
查看次数

Java可以识别CPU的SIMD优势; 或者只有循环展开的优化效果

这部分代码来自我的矢量类的dotproduct方法.该方法对目标矢量数组(1000个矢量)进行内积计算.

当向量长度为​​奇数(262145)时,计算时间为4.37秒.当向量长度(N)为262144(8的倍数)时,计算时间为1.93秒.

     time1=System.nanotime();
     int count=0;
     for(int j=0;j<1000;i++)
     {

             b=vektors[i]; // selects next vector(b) to multiply as inner product.
                           // each vector has an array of float elements.

             if(((N/2)*2)!=N)
             {
                 for(int i=0;i<N;i++)
                 {
                     t1+=elements[i]*b.elements[i];
                 }
             }
             else if(((N/8)*8)==N)
             {
                 float []vek=new float[8];
                 for(int i=0;i<(N/8);i++)
                 {
                     vek[0]=elements[i]*b.elements[i];
                     vek[1]=elements[i+1]*b.elements[i+1];
                     vek[2]=elements[i+2]*b.elements[i+2];
                     vek[3]=elements[i+3]*b.elements[i+3];
                     vek[4]=elements[i+4]*b.elements[i+4];
                     vek[5]=elements[i+5]*b.elements[i+5];
                     vek[6]=elements[i+6]*b.elements[i+6];
                     vek[7]=elements[i+7]*b.elements[i+7];


                     t1+=vek[0]+vek[1]+vek[2]+vek[3]+vek[4]+vek[5]+vek[6]+vek[7];
                     //t1 is total sum of all dot products.
                 }
             }
     }
     time2=System.nanotime();
     time3=(time2-time1)/1000000000.0; //seconds
Run Code Online (Sandbox Code Playgroud)

问题:将时间从4.37s减少到1.93s(快2倍)是JIT明智地决定使用SIMD指令还是只是我的循环展开的正面效果?

如果JIT不能自动进行SIMD优化,那么在这个例子中,JIT也没有自动完成展开优化,这是真的吗?

对于1M迭代(向量)和向量大小为64,加速乘数变为3.5X(缓存优势?).

谢谢.

java optimization performance simd loop-unrolling

4
推荐指数
2
解决办法
7005
查看次数

C++循环展开性能差异(Project Euler)

我有一个关于使用循环展开的Project Euler问题和优化的问题.

问题描述:2520是可以除以1到10中的每个数字而没有任何余数的最小数字.可以被1到20的所有数字整除的最小正数是多少?

解:

#include <iostream>
#include <limits.h>
#include <stdio.h>
#include <time.h>

using namespace std;

int main() {

    clock_t startTime = clock();

    for (int i = 1; i < INT_MAX; i++)
    {
        bool isDivisible = true;

        //CODE BLOCK #1
        /*for (int j = 2; j <= 20; j++)
        {
                if ( i % j != 0)
                {
                        isDivisible = false;
                        break;
                {
        }*/

        //CODE BLOCK #2
        /*if (i % 2 != 0 || i % 3 != 0 ||
                i …
Run Code Online (Sandbox Code Playgroud)

c++ for-loop loop-unrolling

4
推荐指数
1
解决办法
224
查看次数

fortran矢量长度和fortran循环的展开因子

我想用SIMD指令对下面的fortran进行矢量化

!DIR$ SIMD
    DO IELEM = 1 , NELEM
      X(IKLE(IELEM)) = X(IKLE(IELEM)) + W(IELEM)
    ENDDO
Run Code Online (Sandbox Code Playgroud)

我使用了avx2指令.该程序由编译

ifort main_vec.f -simd -g -pg -O2 -vec-report6 -o vec.out -xcore-avx2 -align array32byte
Run Code Online (Sandbox Code Playgroud)

然后我想VECTORLENGTH(n)在之后添加条款SIMD.如果没有这样的条款或n = 2,4,则该信息不提供有关展开因子的信息

如果n = 8,16 , vectorization support: unroll factor set to 2.

我已经阅读了英特尔关于矢量化支持的文章:展开因子设置为xxxx所以我想循环展开到类似:

    DO IELEM = 1 , NELEM, 2
      X(IKLE(IELEM)) = X(IKLE(IELEM)) + W(IELEM)
      X(IKLE(IELEM+1)) = X(IKLE(IELEM+1)) + W(IELEM+1)
    ENDDO
Run Code Online (Sandbox Code Playgroud)

然后2 X进入向量寄存器,2 W进入另一个,进行加法.但VECTORLENGTH的价值如何运作?或许我真的不明白矢量长度是什么意思.

因为我使用avx2指令,对于DOUBLE PRECISION类型X,最大长度是多少?

这是循环组装的一部分,SSE2,VL …

fortran simd vectorization loop-unrolling

4
推荐指数
1
解决办法
493
查看次数

在金属内核中循环展开

我需要强制 Metal 编译器在我的内核计算函数中展开一个循环。到目前为止,我已经尝试放在循环#pragma unroll(num_times)之前for,但编译器忽略了该语句。

似乎编译器不会自动展开循环——我比较了 1) 带有for循环的代码2) 相同代码但带有手动展开循环的执行时间。手动展开的版本快了 3 倍。

例如:我想从这个开始:

for (int i=0; i<3; i++) {
    do_stuff();
}
Run Code Online (Sandbox Code Playgroud)

对此:

do_stuff();
do_stuff();
do_stuff();
Run Code Online (Sandbox Code Playgroud)

在 Metal C++ 语言中甚至有类似循环展开的东西吗?如果是,我怎么可能让编译器知道我想展开一个循环?

kernel ios loop-unrolling metal

4
推荐指数
1
解决办法
868
查看次数

C循环展开优化性能

第一:我知道循环优化是什么以及它是如何工作的我发现了一个我无法解释结果的情况.

我创建了一个质数检查器,它在每个数字上调用模数从2到n - 1,因此没有算法优化.

编辑:我知道素数可以更有效地计算,但这只是循环行为的一个例子.

然后我创建了一个普通版和优化版:

#include <stdlib.h>
#include <stdio.h>

typedef unsigned long long natural;

int is_prime(natural n){
    int is_not_prime = 0;

    for(natural i = 2; i < n; i += 1){
        is_not_prime |= !!!(n % i);
    }

    if(is_not_prime){
        return 0;
    }else{
        return 1;
    }
}

//__attribute__((noinline))
int is_prime_opt(natural n){
    int is_not_prime = 0;

    for(natural i = 2; i < n; i += 8){
        is_not_prime |= !!(
                !(n % i) |
                !(n % i + 1) |
                !(n % i …
Run Code Online (Sandbox Code Playgroud)

c optimization loops loop-unrolling

4
推荐指数
1
解决办法
230
查看次数

在 C 中展开 For 循环

我试图将这个循环展开 2 倍。

for(i=0; i<100; i++){
  x[i] = y[i] + z[i];
  z[i] = y[i] + a[i];
  z[i+1] = y[i] * a[i];
}
Run Code Online (Sandbox Code Playgroud)

我把它展开到:

 for(i=0; i<100; i+=2){
   x[i] = y[i] + z[i];
   x[i+1] = y[i+1] + z[i+1];
   z[i] = y[i] + a[i];
   z[i+1] = y[i] * a[i];
 }
Run Code Online (Sandbox Code Playgroud)

我不确定如何展开 z[i] 的行,因为原始 for 循环已经有 z[i+1]。任何人都可以帮助我理解这一点吗?

c optimization loop-unrolling

4
推荐指数
2
解决办法
286
查看次数