我正在尝试编写一些基准来衡量内联方法的效果.有人知道是否可以在HostSpot JVM上禁用内联特定的类或方法?
我发现-XX:-Inline
总共禁用内联.
在使用跟踪时,我发现在尝试查找它们以便放置断点时,源中未列出一些函数.这些函数似乎只有在我以汇编格式查看源时才会出现.
我和我的前辈交谈过,他们告诉我,如果任何一个函数只被调用一次,它将被Trace优化并显示为内联,因此可以在程序集中看到.
我的问题是:
如果我有一个函数A()
,我有兴趣找到一个方便的方法来创建一个功能B()
完全相同的函数A()
,仅在名称上有所不同.新功能将是一次性使用.目的是在一个有点原始的抽样分析器中区分对相同函数的调用,并且复制函数仅在此上下文中使用.也就是说,它永远不会触及生产代码,只能用于修补.
首先猜测是一个宏,它声明一个名为的函数,B
并A()
在其内部创建一个内联调用.这里的问题是我不知道GCC中强制任意函数调用内联的方法; 似乎所有内联选项都是函数声明而不是调用.
使用模板可能有一些深奥的方法,或者可能通过欺骗编译器进行内联.我不确定这是可能的.有什么想法吗?不幸的是,新的C++标准不可用,如果它会有所作为.
我读到内联函数,在进行函数调用时,我们用函数定义的主体替换函数调用.
根据以上说明,用户何时不应该有任何函数调用inline
.
如果是这种情况为什么我call
在汇编代码中看到三条指令?
#include <iostream>
inline int add(int x, int y)
{
return x+ y;
}
int main()
{
add(8,9);
add(20,10);
add(100,233);
}
meow@vikkyhacks ~/Arena/c/temp $ g++ -c a.cpp
meow@vikkyhacks ~/Arena/c/temp $ objdump -M intel -d a.o
0000000000000000 <main>:
0: 55 push rbp
1: 48 89 e5 mov rbp,rsp
4: be 09 00 00 00 mov esi,0x9
9: bf 08 00 00 00 mov edi,0x8
e: e8 00 00 00 00 call 13 <main+0x13>
13: …
Run Code Online (Sandbox Code Playgroud) 为了代码清晰,我有时创建一个非常明显内联的函数,无论是包装器,还是仅在单个点中调用的函数,或者应该经常调用并且速度快的短函数.
CI会毫不犹豫地对其进行内联,但在Unity/C#中没有办法实现AFAIK(这似乎仅适用于.NET 4.5).
我是否可以相信编译器足够聪明以实际内联,或者我最好有时牺牲代码清晰度来提高性能,不信任编译器?
当然这取决于具体情况,过早的优化是邪恶的,你应该分析而不是猜测.然而,对该主题的一般概述可能仍然有用作为指导,以进行改进.
有没有办法在Visual Studio中执行与"Extract Method"重构相反的方法?
我有一个遗留代码库,它有大约50个非常短的私有函数,每个函数只使用一次,我的任务是内联它们.
如果无法进行自动内联重构,是否可以减少内联这些函数调用所需的时间?我目前的工作流程是:
refactoring inlining automated-refactoring visual-studio-2013
前段时间我读过一些关于"内联"的内容..Net编译器将从小方法注入代码(内联)以更快地执行.
是否有可能来自引用的dll的方法代码在我自己的代码中被内联?
我正在收到警告,例如:
warning: inlining failed in call to ‘symbol_Arity’: call is unlikely and code size would grow
Run Code Online (Sandbox Code Playgroud)
为了摆脱这个我改变了makefile删除-Winline来摆脱这个.我没有得到任何内联警告.但是,我不知道在表现方面做得多么明智.任何人都可以向我推荐一下吗?
添加了一些更多信息:
这是警告:
search.c: In function ‘prfs_InsertInSortTheories’:
list.h:254: warning: inlining failed in call to ‘list_Delete’: call is unlikely and code size would grow
search.c:187: warning: called from here
list.h:254: warning: inlining failed in call to ‘list_Delete’: call is unlikely and code size would grow
search.c:189: warning: called from here
Run Code Online (Sandbox Code Playgroud)
相应的代码是:
来自list.h
254 static __inline__ void list_Delete(LIST L)
255 {
256 LIST Current;
257
258 …
Run Code Online (Sandbox Code Playgroud) 当内联参数中的指针的函数被内联时,编译器是否在优化过程中删除了间接?当然,当它有意义..
这是一个明显的例子:
inline void say_hello (person* p) {
std::cout << "hello " << p->name << std::endl;
}
int main () {
person goldorak;
goldorak.name = "Goldorak";
say_hello(&goldorak);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这种情况是微不足道的,但如果编译器确实进行了优化,那么在某些情况下它不会?
额外奖励:我在哪里可以获得编译器进行的一些"基本"优化列表?
Ps:我只是很好奇
这里我在Derived类中声明了另一个虚函数.
#include <iostream>
using namespace std;
class A{
string s;
public:
A(const string& name) : s(name){}
virtual void f1(){cout << "f1 of base class" << endl;};
};
class B : public A{
string p;
public:
B(const string& name) : A(name){}
virtual void f2(){cout << "virtual function of derived class" << endl;}
void f1(){cout << "f1 of derived class";}
};
int main() {
A* arr[] = {new A("John"),new B("Bob")};
arr[0]->f1();
arr[1]->f1();
arr[1]->f2();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
函数调用arr [1] - > f2() …
我的问题涉及在C++中对函数包装器应用内联优化,考虑以下代码,WorkerStructure对象使用封装了一些功能的函数包装器进行初始化.然后在调用WorkerStructure :: doSomeWork方法时使用函数包装器.
将workerFunction对象封装的功能在应用于WorkerStructure :: doSomeWork方法时会被内联吗?显然,如果在某个其他转换单元中定义了该功能,则workerFunction对象只封装一个函数指针,是否有任何其他情况需要内联不可能吗?
当通过函数包装器传递在不同转换单元中定义的lambda函数时,它是否实际上等效于传递函数指针?
struct WorkerStructure
{
WorkerStructure(std::function <bool(float)> &f):workerFunction(f) {}
void doSomeWork(float inputValue)
{
if(workerFunction(inputValue))
{
//do some conditional operation
}
}
std::function <bool(float)> workerFunction ;
};
Run Code Online (Sandbox Code Playgroud) 我有一个虚拟类Calculator
和该类的示例实现MyCalculator
.
template <class T>
class Calculator{
virtual void op1() = 0;
};
template <class T>
class MyCalculator : public Calculator{
void op1(){ do_something(); }
};
Run Code Online (Sandbox Code Playgroud)
当我使用op1()
以下函数中演示时,编译器当然不能内联,op1()
因为它是虚拟的:
void calculate(Calculator* calc){
calc->op1();
}
Run Code Online (Sandbox Code Playgroud)
但是,在某些情况下,我知道calc
AND 的实际类型,因为性能原因需要内联.所以我想到了以下想法:
template <class C>
void calculate(C* calc){
calc->op1();
}
Run Code Online (Sandbox Code Playgroud)
我会调用这个函数,如下所示:
Calculator c1 = new Calculator();
calculate(c1); // no inling possible in calculate(...)
MyCalculator c2 = new MyCalculator();
calculate(c2); // inlining possible in calculate(...) ?
Run Code Online (Sandbox Code Playgroud)
在第一个例子,内联是不可能的,但我认为在第二个例子中,op1()
的MyCalculator …
我正在尝试制作一些会导致JIT内联的"Hello World"大小的C#代码片段.到目前为止我有这个:
class Program
{
static void Main(string[] args)
{
Console.WriteLine( GetAssembly().FullName );
Console.ReadLine();
}
static Assembly GetAssembly()
{
return System.Reflection.Assembly.GetCallingAssembly();
}
}
Run Code Online (Sandbox Code Playgroud)
我从Visual Studio编译为"Release" - "Any CPU"和"Run without debugging".它显示我的示例程序程序集的名称,因此显然GetAssembly()
没有内联Main()
,否则它将显示mscorlib
程序集名称.
如何编写一些会导致JIT内联的C#代码片段?