标签: loop-unrolling

#pragma unroll做了什么?它会影响线程数吗?

我是CUDA的新手,我无法理解循环展开.我写了一段代码来理解这项技术

__global__ void kernel(float *b, int size)
{
    int tid = blockDim.x * blockIdx.x + threadIdx.x;
 #pragma unroll
    for(int i=0;i<size;i++)
        b[i]=i;
}
Run Code Online (Sandbox Code Playgroud)

以上是我的核心功能.在main我称之为下面

int main()
{
    float * a; //host array
    float * b; //device array
    int size=100;

    a=(float*)malloc(size*sizeof(float));
    cudaMalloc((float**)&b,size);
    cudaMemcpy(b, a, size, cudaMemcpyHostToDevice);

    kernel<<<1,size>>>(b,size); //size=100

    cudaMemcpy(a, b, size, cudaMemcpyDeviceToHost);

    for(int i=0;i<size;i++)
        cout<<a[i]<<"\t";

    _getch();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是否意味着我有size*size= 10000个线程运行来执行程序?在展开循环时是否创建了100个?

cuda nvidia pragma loop-unrolling

24
推荐指数
1
解决办法
3万
查看次数

在g ++上使用聚合初始化的std :: array会生成巨大的代码

在g ++ 4.9.2和5.3.1上,此代码需要几秒钟的时间来编译并生成52,776字节的可执行文件:

#include <array>
#include <iostream>

int main()
{
    constexpr std::size_t size = 4096;

    struct S
    {
        float f;
        S() : f(0.0f) {}
    };

    std::array<S, size> a = {};  // <-- note aggregate initialization

    for (auto& e : a)
        std::cerr << e.f;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

增加size似乎线性增加编译时间和可执行文件大小.我无法使用clang 3.5或Visual C++ 2015重现此行为.使用-Os没有区别.

$ time g++ -O2 -std=c++11 test.cpp
real    0m4.178s
user    0m4.060s
sys     0m0.068s
Run Code Online (Sandbox Code Playgroud)

检查汇编代码显示初始化a已展开,生成4096 movl条指令:

main:
.LFB1313:
    .cfi_startproc
    pushq   %rbx
    .cfi_def_cfa_offset 16
    .cfi_offset …
Run Code Online (Sandbox Code Playgroud)

c++ optimization g++ loop-unrolling stdarray

24
推荐指数
1
解决办法
708
查看次数

如何阻止 Clang 通过模板过度扩展嵌套循环?

考虑这段代码:

#include <iostream>
typedef long xint;
template<int N>
struct foz {
    template<int i=0>
    static void foo(xint t) {
        for (int j=0; j<10; ++j) {
            foo<i+1> (t+j);
        }
    }
    template<>
    static void foo<N>(xint t) {
        std::cout << t;
    }

};

int main() {
    foz<8>::foo<0>(0);
}
Run Code Online (Sandbox Code Playgroud)

在编译时clang++ -O0,它会在几秒钟内编译然后运行 ​​4 秒。

然而,使用clang++ -O2,编译需要很长的时间和大量的内存。在Compiler Explorer上可以看到,更改8为较小的值后,它完全展开了循环。

我并不是让它完全没有优化,而是让它不递归,就像嵌套循环应该表现的那样。有什么我应该做的吗?

c++ clang compiler-optimization template-meta-programming loop-unrolling

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

替代if,否则if

我有很多if,else if语句,我知道必须有更好的方法来做到这一点,但即使在搜索stackoverflow之后,我也不确定如何在我的特定情况下这样做.

我正在解析文本文件(账单)并根据账单上是否出现某些字符串将服务提供商的名称分配给变量(txtvar.Provider).

这是我正在做的一小部分样本(不要笑,我知道它很乱).总而言之,如果是,那么大约有300个.

if (txtvar.BillText.IndexOf("SWGAS.COM") > -1)
{
    txtvar.Provider = "Southwest Gas";
}
else if (txtvar.BillText.IndexOf("georgiapower.com") > -1)
{
    txtvar.Provider = "Georgia Power";
}
else if (txtvar.BillText.IndexOf("City of Austin") > -1)
{
    txtvar.Provider = "City of Austin";
}
// And so forth for many different strings
Run Code Online (Sandbox Code Playgroud)

我想使用类似switch语句的东西更高效和可读,但我不确定如何比较BillText.我正在寻找这样的东西,但无法弄清楚如何使它工作.

switch (txtvar.BillText)
{
    case txtvar.BillText.IndexOf("Southwest Gas") > -1:
        txtvar.Provider = "Southwest Gas";
        break;
    case txtvar.BillText.IndexOf("TexasGas.com") > -1:
        txtvar.Provider = "Texas Gas";
        break;
    case txtvar.BillText.IndexOf("Southern") > -1:
        txtvar.Provider = "Southern Power & Gas"; …
Run Code Online (Sandbox Code Playgroud)

c# performance dictionary if-statement loop-unrolling

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

C/C++中的自展开宏循环

我目前正在开展一个项目,每个周期都很重要.在分析我的应用程序时,我发现一些内部循环的开销非常高,因为它们只包含一些机器指令.另外,这些循环中的迭代次数在编译时是已知的.

所以我认为不是手动展开带有复制和粘贴的循环,而是可以使用宏在编译时展开循环,以便以后可以轻松修改它.

我的形象是这样的:

#define LOOP_N_TIMES(N, CODE) <insert magic here>
Run Code Online (Sandbox Code Playgroud)

所以我可以替换for (int i = 0; i < N, ++i) { do_stuff(); }为:

#define INNER_LOOP_COUNT 4
LOOP_N_TIMES(INNER_LOOP_COUNT, do_stuff();)
Run Code Online (Sandbox Code Playgroud)

它将自己展开:

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

由于C预处理器在大多数时间对我来说仍然是一个谜,我不知道如何实现这一点,但我知道它必须是可能的,因为Boost似乎有一个BOOST_PP_REPEAT宏.不幸的是我不能在这个项目中使用Boost.

c c++ macros boost loop-unrolling

14
推荐指数
3
解决办法
2万
查看次数

如何使用g ++对我的循环进行矢量化?

我在搜索时找到的介绍性链接:

  1. 6.59.14循环特定的Pragma
  2. 2.100 Pragma Loop_Optimize
  3. 如何给出关于循环计数的gcc的提示
  4. 告诉gcc专门展开一个循环
  5. 如何在C++中强制进行矢量化

正如你所看到的,大多数是C语言,但我认为它们也适用于C++.这是我的代码:

template<typename T>
//__attribute__((optimize("unroll-loops")))
//__attribute__ ((pure))
void foo(std::vector<T> &p1, size_t start,
            size_t end, const std::vector<T> &p2) {
  typename std::vector<T>::const_iterator it2 = p2.begin();
  //#pragma simd
  //#pragma omp parallel for
  //#pragma GCC ivdep Unroll Vector
  for (size_t i = start; i < end; ++i, ++it2) {
    p1[i] = p1[i] - *it2;
    p1[i] += 1;
  }
}

int main()
{
    size_t n;
    double x,y;
    n = 12800000;
    vector<double> v,u;
    for(size_t i=0; i<n; ++i) {
        x …
Run Code Online (Sandbox Code Playgroud)

c++ optimization g++ vectorization loop-unrolling

13
推荐指数
1
解决办法
1万
查看次数

如果在编译时它的迭代次数未知,GCC如何展开循环呢?

当我找到选项时,我正在阅读GCC优化选项-funroll-all-loops.

其描述如下:

展开所有循环,即使在输入循环时它们的迭代次数不确定.这通常会使程序运行得更慢.'-funroll-all-loops'意味着与'-funroll-loops'相同的选项

如果编译时迭代次数未知,编译器如何展开循环?编译器是否需要此信息才能展开它?它产生了哪些相应的C代码,如果它通常使程序运行得更慢,在什么情况下这可能是有用的?

c optimization gcc loop-unrolling

13
推荐指数
1
解决办法
1956
查看次数

优化编译器如何决定展开循环的时间和数量?

当编译器执行循环展开优化时,它如何确定展开循环的因素或是否展开整个循环?由于这是空间性能权衡,平均而言,这种优化技术在使程序运行得更好方面效率如何?此外,在什么条件下建议使用这种技术(即某些操作或计算)?

这不必特定于某个编译器.它可以是任何解释,概述这种技术背后的想法以及在实践中观察到的内容.

c c++ performance compiler-optimization loop-unrolling

10
推荐指数
1
解决办法
2874
查看次数

现代编译器能否展开使用begin和end迭代器表示的`for`循环

请考虑以下代码

 vector<double> v;
 // fill v
 const vector<double>::iterator end =v.end();
 for(vector<double>::iterator i = v.bgin(); i != end; ++i) {
   // do stuff
 }
Run Code Online (Sandbox Code Playgroud)

像g ++,clang ++,icc这样的编译器是否能够像这样展开循环.不幸的是,我不知道汇编能够从输出验证循环是否展开.(我只能访问g ++.)

对我来说,这似乎需要代表编译器比平常更聪明,首先推断迭代器是一个随机访问迭代器,然后计算循环执行的次数.编译器可以在启用优化时执行此操作吗?

感谢您的回复,在您开始讲授过早优化之前,这是一个好奇心的练习.

c++ stl loop-unrolling

10
推荐指数
2
解决办法
2573
查看次数

强制/说服/欺骗GCC展开_Longer_循环?

我如何说服GCC展开一个已知迭代次数但又很大的循环?

我正在编译-O3.

当然,有问题的真实代码更复杂,但这是一个具有相同行为的简化示例:

int const constants[] = { 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144 };

int get_sum_1()
{
    int total = 0;
    for (int i = 0; i < CONSTANT_COUNT; ++i)
    {
        total += constants[i];
    }
    return total;
}
Run Code Online (Sandbox Code Playgroud)

...如果CONSTANT_COUNT被定义为8(或更少),那么GCC将展开循环,传播常量,并将整个函数简化为简单return <value>;.另一方面,如果CONSTANT_COUNT是9(或更高),那么循环不会展开,并且GCC会生成一个二进制循环,读取常量,并在运行时添加它们 - 即使理论上,该函数仍然可以被优化到只返回一个常数.(是的,我看过反编译的二进制文件.)

如果我手动展开循环,如下所示:

int get_sum_2()
{
    int total = 0;
    total += constants[0];
    total += constants[1];
    total += constants[2];
    total += constants[3];
    total …
Run Code Online (Sandbox Code Playgroud)

c gcc loop-unrolling

9
推荐指数
1
解决办法
563
查看次数