我有一个关于C编译器优化以及内联函数中的循环何时/如何展开的问题。
我正在开发一个数字代码,它可以完成下面的示例。基本上,my_for()
将计算某种模具,并调用op()<-code>对每个
包装
my_type*argmy_func()
my_for()<-code>,创建参数并将函数指针发送到
…谁的工作是为每个(
th double-
typedef struct my_type {
int const n;
double *dest[16];
double const *src[16];
} my_type;
static inline void my_for( void (*op)(my_type *,int), my_type *arg, int N ) {
int i;
for( i=0; i<N; ++i )
op( arg, i );
}
static inline void my_op( my_type *arg, int i ) {
int j;
int const n = arg->n;
for( j=0; j<n; ++j )
arg->dest[j][i] += arg->src[j][i];
}
void my_func( double *dest0, double *dest1, double const *src0, double const *src1, int N ) {
my_type Arg = {
.n = 2,
.dest = { dest0, dest1 },
.src = { src0, src1 }
};
my_for( &my_op, &Arg, N );
}
这工作正常。这些函数是内联的,代码(几乎)与在单个函数中内联编写所有内容并展开
j
循环一样高效,无需任何类型的my_type Arg
。
这里的混乱:如果我设置
int const n=2;
而不是int const n=arg-
在我的数字代码中,这相当于大约15%的性能命中率。如果重要的话,这里的
n=4
和这些j
循环出现在
中的两个条件分支中。
我正在用icc(国际商会)12.1.5 20120612编译。我尝试了< code>#pragma unroll
。以下是我的编译器选项(我错过了什么好的吗?):
-
O3 -IPO -静态 -展开-激进 -FP-模型精确 -FP-模型源 -openmp -std=gnu99 -Wall -Wextra -Wno-未使用 -Winline -pedantic
谢谢
它更快,因为您的程序不会为变量分配内存。
如果不必对未知值执行任何操作,则会将它们视为带有类型检查的#define常量2
。它们只是在编译时添加的。
请您从两个标记中选择一个(我的意思是C或C),这很令人困惑,因为语言对const
值的处理方式不同-C将它们视为普通变量,其值不能更改,在C语言中,它们有或没有根据上下文分配内存(如果您需要它们的地址,或者如果您需要在程序运行时计算它们,则分配内存)。
来源:“用C语言思考”。没有确切的引用。
很明显,编译器不够“聪明”,无法传播n
常量并展开for
循环。事实上,它很安全,因为<code>arg-
为了在编译器生成过程中保持一致的性能,并最大限度地压缩代码,请手动展开。
像我这样的人在这种情况下(性能为王)所做的就是依赖宏。
宏将在调试构建中“内联”(有用),并且可以使用宏参数进行模板化(到某一点)。作为编译时常量的宏参数保证保持这种方式。
函数是一个可以重复使用的代码块,CPU 会一条一条地挨着执行其中的代码。CPU 在执行主调函数代码时如果遇到了被调函数,主调函数就会暂停,CPU 转而执行被调函数的代码;被调函数执行完毕后再返回到主调函数,主调函数根据刚才的状态继续往下执行。 一个 C/ C++ 程序的执行过程可以认为是多个函数之间的相互调用过程,它们形成了一个或简单或复杂的调用链条,这个链条的起点是 main(),终点也是 ma
C++ 类 & 对象 C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。 对内联函数进行任何修改,都需要重新编译函数的所有客户端,因为编译器需要重新更换一次所有的代码,否则将会继续使用旧的函数。 如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果已定义的函数多
例如,我在golang中进行了以下测试: 如果我尝试构建它,我会收到以下内容: 有没有办法让编译器内联?如果是,是否有任何方法可以内联映射迭代?
问题内容: 我有以下代码返回而不是循环内的每个值。 我需要怎么做才能获得循环值? 问题答案: 用 IIFE 封闭 **** 这样的话,价值将被保留,该次迭代的而不是将其设置为时间的最后一个值被称为回
本文向大家介绍C和C ++中的循环,包括了C和C ++中的循环的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将讨论一个程序,以了解C和C ++中的循环。 当我们不得不一次又一次地执行给定的块代码时,使用编程中的循环。它采用了一次又一次编写同一代码行的方法,并促进了DRY代码实践。 示例 对于循环 输出结果 While循环 输出结果
我在一个循环中调用了一个异步函数来发送电子邮件,但是有一段时间控件没有返回,也没有发送电子邮件,但是主UI线程完成了。 当我把等待任务。WhenAll(发送电子邮件任务);循环内的线工作正常,但当我把这条线放在循环外时,它不工作,但实际上它应该在循环外。我在sendEmail方法中有很多异步方法,所以我认为有些线程彼此重叠。任何线索。