c++ - 我需要做什么才能获得在编译器优化代码中调用的函数?

标签 c++ ios optimization compilation llvm

我正在使用 Apple LLVM 4.0 进行优化编译 ios 项目。我实现了一个函数的两个不同版本,一个在 C 中,一个在 NEON 中。我想测试他们对彼此的表现。我的想法是将它们都调用相同的次数,然后在 Time Profiler 中查找它们以查看各自花费的相对时间。最初我的代码看起来像

used_value = score_squareNEON(patch, image, current_pos);
used_value = score_squareC(patch, image, current_pos);

当我剖析的时候NEON代码根本没有出现。接下来我尝试了

for(int i = 0; i < successively_bigger_numbers; i++)
{
    used_value = score_squareNEON(patch, image, current_pos);
{
used_value = score_squareC(patch, image, current_pos);

仍然没有来自 NEON 代码的贡献。接下来是

used_value = score_squareNEON(patch, image, current_pos);
test = score_squareC(patch, image, current_pos);

测试从未被读取。没有什么。然后

test = score_squareNEON(patch, image, current_pos);
test = 0;
other_used_variable += test;
used_value = score_squareC(patch, image, current_pos);

仍然没有。最终使它执行这两个功能的是

value = score_squareNEON(patch, image, current_pos);
test = score_squareC(patch, image, current_pos);
...
min = (value+test)/2; //before it was min=value;

也很重要。这些函数都在我调用它们的同一个文件中定义。当我尝试将函数声明移动到不同的文件时,每个示例都会调用它们。

首先,我对编译器非常尊重。其次,我究竟需要做什么才能确保函数被调用?这让我开始质疑我之前计时的所有事情。如果在正常模式下怎么办

timerStart();
functionCall();
timerEnd();

中间的函数被完全优化掉了?我是否需要每次都以某种方式开始检查,或者我可以使用一些技巧吗?编译器何时可以优化整个函数调用的规则是什么?

最佳答案

Also very important. The functions were both defined in the same file in which I was calling them. When I tried moving the function declarations to a different file both of them are called in every example.

当编译器可以证明一个函数调用没有副作用,并且它的结果没有被使用时,它可以移除这个调用。如果不能证明这一点,则不能删除该调用,因为就编译器而言,该函数可能有副作用,并且不能消除这些副作用。

声明将函数调用的结果分配给的变量¹应该足以强制编译器将函数调用留在程序中(6.7.3,N1570 中的第 7 段):

An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3. Furthermore, at every sequence point the value last stored in the object shall agree with that prescribed by the abstract machine, except as modified by the unknown factors mentioned previously. What constitutes an access to an object that has volatile-qualified type is implementation-defined.

据我所知,对于 C++,保证没有那么明确,但我认为 1.9 应该优先:

程序执行,1.9(6)和(7):

The observable behavior of the abstract machine is its sequence of reads and writes to volatile data and calls to library I/O functions.6)

Accessing an object designated by a volatile lvalue (3.10), modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment. Evaluation of an expression might produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.

在 7.1.5.1 中:

[Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C++ as they are in C. ]

¹ 当然,这不适用于 void fun()

关于c++ - 我需要做什么才能获得在编译器优化代码中调用的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11782973/

相关文章:

performance - 分支错误预测在哈希表查找性能中起什么作用?

MySql - 进一步查询优化SELECT WHERE IN

c++ - 使用带有 unique_ptr 的自定义删除器

c++ - Visual C++ 测试开箱即用项目中的错误

c++ - 如何将这些 c 代码行转换为 c++

ios - 在 iOS 上绘制圆角图像时遇到奇怪的锯齿

mysql - AWS 2x.large 服务器 Apache 和 Mysql 配置没有很好地利用 CPU 和内存

c++ - 我可以在我自己的应用程序中使用在 Windows 资源管理器中看到的搜索框控件吗?

ios - 无法将结构从非托管库编码为单触摸中的托管代码

ios - 调用动画后 UIImage View 重置