2017-07-04 50 views
1

我们正在创造一个Android应用程序来比较ART和本地代码之间的执行时间。我们正在使用Android Studio和CMake编译C/C++。CMAKE_BUILD_TYPE发布:奇怪的结果

当CMakeList.txt我们设置标志

set(CMAKE_BUILD_TYPE Release) 

在一些算法(素性测试和斐波那契)的执行时间急剧下降为0ms所有不同的输入。

这里的本地库

bool flag = false; 

extern "C" JNIEXPORT void JNICALL Java_javacpp_cmr_com_sdkvsndk_MainActivity_cancel(JNIEnv *env, jobject obj) { 
     flag = true; 
    } 


extern "C" JNIEXPORT jlong JNICALL Java_javacpp_cmr_com_sdkvsndk_MainActivity_primalityTest(JNIEnv *env, jobject obj, jlong r) { 
    if(r < 0) return -1L; 
    timeval start, stop; 
    long long t; 
    gettimeofday(&start, NULL); 

    bool prime = true; 

    unsigned long long sr = (unsigned long long) sqrt(r); 
    for (unsigned long long i = 2; (i < sr) && prime; i++) { 
     if (flag) return -1; 
     if (r % i == 0) prime = false; 
    } 

    gettimeofday(&stop, NULL); 
    t = (stop.tv_sec - start.tv_sec) * 1000; 
    t += (long long) ((stop.tv_usec - start.tv_usec)/1000) 
    return (jlong) t; 
    } 

标志是,当我们终止执行该算法的AsyncTask被设置为true的标志。

我不知道这是如何可能的。任何建议?谢谢。

+2

因为优化的?查看生成的(汇编)代码以查看它的功能。 –

+2

优化...你没有使用循环的计算结果,所以编译器摆脱它 – Selvin

+0

这是有道理的,谢谢。有一种方法可以告诉编译器该标志可以在外部修改吗?所以它必须进入循环,因为它可以返回-1 –

回答

0

这是因为默认情况下你的CMake的项目是建立与Debug类型。在这种类型的调试信息生成以及优化被禁用(-O0 -g标志为gcc)。

这是为了使您能够一步槽由线C++代码行,它是由你。如果将类型更改为Release,则优化会打开,并且调试信息不​​包含在二进制文件中。

的优化技术使代码跑得那么快,不管你如何认为你写的东西,编译器仍然是领先的你,会做的更好。然而,当代码被调试时,这些优化会显示不稳定的行为,行不按顺序执行,或根本不显示,变量不在手表中显示或显示错误,这对调试并不好。

丢失的调试信息表示二进制较轻,但如果你需要调试的更好做法,因为对C++的哪一行的任何信息的一些组件,导致这些汇编指令都将丢失。作为一个方面说明,还有RelWithDebugInfo构建类型,以防您真的需要调试优化的代码。

通常情况下,Android Studio中应注意适当的构建类型的给你们,就没有必要与乱动。

0

你可以转储用于构建使用C/C++源文件编译的命令:在CMakeLists.txt set(CMAKE_EXPORT_COMPILE_COMMANDS ON)这将创造一个compile_commands.json build目录。

您可以尝试的“CMAKE_BUILD_TYPE”不同的组合,并保存为不同的生成类型生成compile_commands.json针对不同的编译器标志为优化,调试等