簡體   English   中英

GCC 和 Clang 之間的執行性能差距

[英]Executing performance gap between GCC and Clang

我有以下簡單的代碼,當我在 GCC 和 Clang 中編譯它們時,它們的執行時間之間存在巨大的性能差異,您可以在下面看到結果和編譯器的版本。

char* strchr_x(register const char* s, int c) {
  do {
    if (*s == c) {
      return (char*)s;
    }
  } while (*s++);

  return 0;
}
char* get(char* value, const char separator) {
  int separator_index = strchr(value, separator) - value;
  char* result = malloc(separator_index);
  memcpy(result, value, separator_index);
  result[separator_index] = '\0';

  return result;
}
int main() {
  const char separator = ',';
  clock_t t = clock();

  for (size_t i = 0; i < 100000000; ++i) {
    free(get("127.0.0.1, 127.0.0.2:1111", separator));
  }

  float elapsed_seconds = (((double)(clock() - t)) / CLOCKS_PER_SEC);
  printf("%f seconds.\n", elapsed_seconds);

  return 0;
}
gcc version 8.1.0 (Ubuntu 8.1.0-5ubuntu1~16.04)
# gcc main.c -O3 -o gcc-main
# 1.968750 seconds.

clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
# clang main.c -O3 -o clang-main
# 0.000000 seconds.

此外,“strchr_x”實現與原始 GCC 實現完全相同。 您可以在https://github.com/gcc-mirror/gcc/blob/master/libiberty/strchr.c看到它

當我在標准庫中使用'strchr'方法時; GCC 的運行時間減少到 0.015625 秒。

所以,我的問題是:

  1. 為什么在 GCC 中我的“strchr_x”和標准庫的“strchr”之間存在巨大的性能差異?
  2. 為什么 GCC 和 Clang 之間存在巨大的性能差距?

如果您將代碼插入https://godbolt.org/中,您會看到 Clang 將優化整個 for 循環,這就解釋了為什么它在 0 秒內執行。 它可能會這樣做,因為 get 的唯一副作用是 malloc,並且結果會立即釋放。

編輯:GCC 看起來你的代碼確實做得不太好......我再次檢查了生成的匯編程序,不僅僅是它沒有刪除空的for循環(for strchr()),而且它失敗了刪除循環體中的 function 調用(對於 strchr_x())。

所以最后這一切都歸結為一些非常奇怪的優化行為,你最慢的例子實際上是唯一一個做任何事情的例子。 我不知道為什么GCC 在您的示例中如此失敗,但我絕對同意您應該將此作為錯誤提交(甚至可能是兩個單獨的錯誤,因為它在使用 strchr() 時已經很難失敗,使用 strchr_x 時更難(),即使兩者應該相同)

似乎gcc無法刪除循環,即使它刪除了循環內的調用。 這是帶有提到的代碼的godbolt鏈接: https://godbolt.org/z/5wamhm

main:
        push    rbx
        call    clock
        mov     rbx, rax
        mov     eax, 100000000
.L5:
        sub     rax, 1 // <<-------- loop which does nothing.
        jne     .L5
        call    clock

這絕對值得在 gcc bugzilla 中提交錯誤。 我在這里提交錯誤: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92638

問題二的簡短答案clang (LLVM) 在運行時具有更好的代碼和鏈接優化。

現在,我將首先從經驗中舉出一個例子。 我從事的項目套裝需要在 raspberry pi-3 設備上進行測試。 當我使用clang++編譯時,大約需要 15 分鍾,而使用gcc時,經過 40 多分鍾的漫長等待編譯,就在鏈接的最后,構建只是用完了 memory? 為什么, clang提供了更好的編譯時代碼優化和后台鏈接。

但是,這取決於,在不同的 Ox 水平下,您可能不會得到相同的差異(嘗試使用 O2,您會看到)。 為了獲得更多參考,我認為這兩篇文章提供了一些詳細的解釋。

https://medium.com/@alitech_2017/gcc-vs-clang-llvm-an-in-depth-comparison-of-cc-compilers-899ede2be378

https://clang.llvm.org/comparison.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM