C 在for循环中高效地打印每x次迭代

C 在for循环中高效地打印每x次迭代,c,performance,hpc,C,Performance,Hpc,我正在编写一个程序,其中某个for循环被多次迭代 一次迭代不会花费很长时间,但由于程序经常迭代循环,因此计算需要相当长的时间 为了在不放慢进度的情况下获得更多关于项目进度的信息,我想每第X步打印一次进度 是否有一种不同的方法来实现这一点,而不是像这样使用模的条件: for(int i = 0; i < some_large_number; i++){ if(i % x == 0) printf("%f%%\r", percent); //some other

我正在编写一个程序,其中某个for循环被多次迭代

一次迭代不会花费很长时间,但由于程序经常迭代循环,因此计算需要相当长的时间

为了在不放慢进度的情况下获得更多关于项目进度的信息,我想每第X步打印一次进度

是否有一种不同的方法来实现这一点,而不是像这样使用模的条件:

for(int i = 0; i < some_large_number; i++){
    if(i % x == 0)
        printf("%f%%\r", percent);
    //some other code
    .
    .
    .
}
for(int i=0;i
?


谢谢是预付款

我会这样做:

intj=x;
for(int i=0;i
关于性能问题,最快的方法是使用嵌套循环:

unsigned int x = 6;
unsigned int segments = some_large_number / x; 
unsigned int y;

for ( unsigned int i = 0; i < segments; i++ ) {

    printf("%f%%\r", percent); 

    for ( unsigned int j = 0; j < x; j++ ) {

       /* some code here */

    }
}


// If some_large_number can´t be divided evenly through `x`:

if (( y = (some_large_number % x)) != 0 )
{
    for ( unsigned int i = 0; i < y; i++ ) {

       /* same code as inside of the former inner loop. */

    }
}

将某个大数字除以x。现在循环x次,用新的整数嵌套,然后打印百分比。我的意思是:

int temp = some_large_number/x;
for (int i = 0; i < x; i++){
   for (int j = 0; j < temp; j++){
        //some code
   }
   printf("%f%%\r", percent);
}
int temp=some\u large\u number/x;
对于(int i=0;i
此代码:

for(int i = 0; i < some_large_number; i++){
    if(i % x == 0)
        printf("%f%%\r", percent);
    //some other code
    .
    .
    .
}
for(int i=0;i
可重组为:

/*  Partition the execution into blocks of x iterations, possibly including a
    final fragmentary block.  The expression (some_large_number+(x-1))/x
    calculates some_large_number/x with any fraction rounded up.
*/
for (int block = 0, i = 0; block < (some_large_number+(x-1))/x; ++block)
{
    printf("%f%%\r", percent);

    //  Set limit to the lesser of the end of the current block or some_large_number.
    int limit = (block+1) * x;
    if (some_large_number < limit) limit = some_large_number;

    //  Iterate the original code.
    for (; i < limit; ++i)
    {
        //some other code
    }
}
/*将执行划分为x个迭代块,可能包括
最后的碎片块。表达式(一些大数+(x-1))/x
计算某个大数值/x,并将任何分数向上舍入。
*/
对于(int block=0,i=0;block<(一些大数字+(x-1))/x;++block)
{
printf(“%f%%\r”,百分比);
//将“限制”设置为当前块末尾或某个大数字中的较小值。
整数极限=(块+1)*x;
如果(某个大数<极限)极限=某个大数;
//迭代原始代码。
对于(;i
具有以下注意事项和特性:

  • 内部循环的工作量不超过原始循环(它没有额外的变量进行计数或测试),并且已完全删除
    i%x==0
    test。这对于内循环来说是最佳的,因为它尽可能减少了名义工作量,尽管现实世界的硬件有时会有挑剔的行为,这会导致用更少的实际工作量来计算更多的时间
  • 引入了新的标识符
    限制
    ,但可以进行更改,以避免与原始代码中的使用发生任何冲突
  • 除上述内容外,内部循环的操作方式与原始代码相同:它以与原始代码相同的顺序查看相同的
    i
    ,因此不需要对该代码进行任何更改
  • 一些大数字+(x-1)
    可能溢出
    int

这是性能问题吗?如果模是性能问题,请使用计数器。嵌套循环更快。当然,I/O将主导性能;相比之下,模计算速度更快。如果你选择2的幂,你还可以将最后一位的掩码与比除法快的0进行比较(你的编译器甚至可以在优化时为你做这件事)。@Yunnosch:“用不同的方法进行,然后测量”是一个锤子。熟练的实践者学习处理器规范,学习系统如何运行,并应用推理来设计潜在的解决方案,将许多部分组合在一起,以复杂的代码实现。人们不能指望通过反复试验来找到优化缓存使用的最佳阵列几何体,正如人们不能通过将碎片粉碎在一起来制造一块精致的机械表一样。推荐测量作为优化的主要工具对学生来说是一个坏建议。最好的工具是知识。这是一个正确的方法,但细节是错误的。内部循环应运行
x
次迭代,而不是
temp
,因为需要每
x
次迭代打印一次。因此外部循环应该运行
temp
迭代。当
x
不能平均分割
一些大数时,需要一些代码来处理左ovr的片段。此外,
i
的原始值可能会在原始循环的主体中使用,在这种情况下,必须制定一些规定以使其可用。例如,可以执行
int numberofwholeblock=some\u large\u number/x;对于(int block=0;block
用于外循环,对于(int i=block*x;i<(block+1)*x;++i)
用于内循环。然后,在内部循环中,
i
的值始终与原始代码的相应迭代中的值相同。关键概念是x*temp=some\u large\u numbers您可以选择x*temp或temp*x这是我们迄今为止尝试的解决方案中的选择这似乎是最快的,而不是减去并与0比较,我将x相加,然后将变量设置回0。这将添加另一个计数器。如前所述,这是不必要的,因为使用嵌套循环会导致大多数迭代的成本不比原始代码高,因为没有额外的变量需要增加和测试。内部循环只是以“全速”运行,只有当它终止时,才有一点额外的打印工作要做hair@EricPostpischil如果不完全重构循环代码,我就无法真正实现嵌套循环…@EricPostpischil啊,是的,对不起,我忽略了你评论中的那一部分
/*  Partition the execution into blocks of x iterations, possibly including a
    final fragmentary block.  The expression (some_large_number+(x-1))/x
    calculates some_large_number/x with any fraction rounded up.
*/
for (int block = 0, i = 0; block < (some_large_number+(x-1))/x; ++block)
{
    printf("%f%%\r", percent);

    //  Set limit to the lesser of the end of the current block or some_large_number.
    int limit = (block+1) * x;
    if (some_large_number < limit) limit = some_large_number;

    //  Iterate the original code.
    for (; i < limit; ++i)
    {
        //some other code
    }
}