簡體   English   中英

glibc使用內核函數

[英]glibc uses kernel functions

我試圖從glibc源代碼中了解此方法:

    26 #if LIBM_SVID_COMPAT
    27 /* wrapper sqrtf */
    28 float
    29 __sqrtf (float x)
    30 {
    31   if (__builtin_expect (isless (x, 0.0f), 0) && _LIB_VERSION     != _IEEE_)
    32     return __kernel_standard_f (x, x, 126); /*    sqrt(negative) */
    33 
    34   return __ieee754_sqrtf (x);
    35 }
    36 libm_alias_float (__sqrt, sqrt)
    37 #endif

據我了解,如果程序無法從glibc中找到sqrt函數的有效實現,它將從內核調用硬件函數,即特定的機器函數。 這是正確的嗎?
另外, libm_alias_float (__sqrt, sqrt)是什么意思?

GNU C庫的數學功能在“ glibc”源代碼樹中完全實現。 他們什么都不依賴操作系統內核。 在此上下文中,“內核”一詞指的是計算內核,這是某些數學算法的核心,您可能想用手工優化的匯編語言編寫該部分。

函數__kernel_standard_f被錯誤命名。 它包含用於處理數學函數錯誤的通用代碼。 最好將其命名為__math_domain_error 在這種情況下,當__sqrtf的參數為負數時, __sqrtf調用__kernel_standard_f __kernel_standard_f然后將把errnoEDOM ,可能會調用SVID matherr回調,並返回NaN。 (神秘代碼126告訴__kernel_standard_f該函數調用它,為什么。的執行__kernel_standard_fsysdeps/ieee754/k_standardf.csysdeps/ieee754/k_standard.c 。)

條件_LIB_VERSION != _IEEE_與是否啟用POSIX和/或SVID數學錯誤處理有關; 現代數學算法實際上只希望在結果中查找NaN,而沒有浪費庫時間設置errno或調用matherr ,因此有一種機制可以將后兩者關閉。

如果__sqrtf的參數不是負數,則尾部將調用__ieee754_sqrtf ,它執行平方根的實際計算。 glibc源代碼樹中有此功能的幾種替代實現。 其僅C的通用版本在sysdeps/ieee754/flt-32/e_sqrtf.c (即使按照glibc的標准,實現數學功能的文件的名稱也是神秘的。我不必費心去理解它們,我只是find sysdeps -name '*sqrtf*'或其他名稱。)此功能以邏輯開始檢測一個負參數(也為零,無窮大和NaN)並返回適當的值,但它不會碰到errno 如果您想了解用於計算平方根的數學技術,請查看此文件。

如果您自己運行上述find命令,則會發現其他幾個名為e_sqrtf.c文件; 這些都在以特定CPU命名的目錄中,這些CPU的浮點單元對計算平方根具有硬件支持,因此sysdeps/x86_64/fpu/e_sqrt.c讀取

double
__ieee754_sqrt (double x)
{
  double res;

  asm ("sqrtsd %1, %0" : "=x" (res) : "xm" (x));

  return res;
}

因為x86 sqrtsd指令可以完成全部工作。

當為其中一個CPU進行構建時,Glibc的構建過程將選擇這些文件之一,而不是通用C版本。 這種機制很復雜,並且沒有完整記錄,但是glibc手冊的“維護”附錄 ,特別是其“源布局”和“移植”部分,對它進行了詳盡的介紹。


libm_alias_float (__sqrt, sqrt)安排__sqrtf也使用名稱sqrtf ,但作為弱別名 為了符合標准,這是必需的。 如果您需要更多詳細信息,請問一個單獨的問題。

暫無
暫無

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

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