2017-07-04 46 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針對不同的編譯器標誌爲優化,調試等