TZY
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # 2019q3 Homework1 (review) contributed by < `nckuoverload` > ###### tags: `sysprog2019` ## 作業要求 * 從 [課程簡介和注意須知](https://docs.google.com/presentation/d/1Wo22s5aYuuyry97-z2MMmUmdxhjD0wKTdhxIW5oqjvo/edit?usp=sharing), [第 1 週測驗題](https://hackmd.io/@sysprog/HksKVpUIr) 選出你感興趣的 3 個題組進行作答,並且回答附帶的「延伸問題」 * 應當包含 [課程簡介和注意須知](https://docs.google.com/presentation/d/1Wo22s5aYuuyry97-z2MMmUmdxhjD0wKTdhxIW5oqjvo/edit?usp=sharing) 的 Page 9 到 Page 16 裡頭的 C 語言程式設計議題 * 比照 [課前測驗參考解答: Q1](https://hackmd.io/s/ByzoiggIb) 和 [對 Linked List 進行氣泡排序](https://hackmd.io/s/BklGm1MhZ) 的模式來撰寫共筆,需要詳細分析自己的想法、參閱的材料 (包含 C 語言規格書的章節),以及==進行相關實驗== * 閱讀 [第一週課程進度](http://wiki.csie.ncku.edu.tw/sysprog/schedule) 所有材料,記錄所見所聞並提問,若有不能理解的部分,請標註出來。善用 HackMD 的語法 `:::info` 和 `:::` 標註你的提問 :::info 像是這樣標註提問 ::: :::danger 注意共筆書寫的規範: 1. 中英文之間應以空白字元區隔; 2. 偏好的程式碼縮排是 K&R 風格和 4 spaces; :notes: jserv ::: ## 改善精準度 根據wiki和等頁面資料,可以快速的理解IEEE-754和浮點數運算會產生的問題。 在一些空間受限的情況中,無法改變、擴充資料結構,因此這時候並須以有限的資源方式去改善精準度問題。另外在[浮點數的美麗與哀愁](https://champyen.blogspot.com/2017/04/blog-post.html) 這篇文章中,也有討論到這個議題,內文分別對IEEE-754 Format本身、CPU 間的問題、GPU等去討論。 ### 解決方法 解決方法的部份,可以參考自[Estimating Errors In Summing Arrays Of Floating Point Numbers](https://www.reidatcheson.com/statistics/floating%20point/error/2018/01/15/float-sum-errors.html) 中,他分別都提到 Kahan summation, Pairwise summation 演算法,以及他對最壞偏差情況做的實驗。兩個演算法可分別參考wiki 。 ### Kahan summation algorithm 簡單來說,在每次加減完後,對該次的運算偏差作修正。 ```cpp #include <stdio.h> int main() { float sum = 0.0f, corr = 0.0f; /* corrective value for rounding error */ for (int i = 0; i < 10000; i++) { float y = (i + 1) - corr; /* add the correction to specific item */ float t = sum + y; /* bits might be lost */ corr = (t - sum) - y; /* recover lost bits */ sum = t; } printf("Sum: %f\n", sum); // output: 50005000.000000 return 0; } ``` corr變數用來當作每次運算完之後的偏差量,在一開始的運算,浮點數偏差可能為0。但經過多次運算後,逐漸會產生偏差,這時候使用corr來儲存偏差,並且在下一次的運算中彌補。 偏差的計算可以參考下列程式碼: ```cpp #include <stdio.h> int main(){ float a = 123456.0; float b = 3.141; printf("the sum is: %f",a+b); printf("the corr is: %f",a+b-a-b); } ``` 運算結果為 ```shell the sum is: 123459.140625 the corr is: -0.000375 ``` ### Pairwise summation 簡單來說,在一定的運算次數N 內,並不會產生偏差,因此運用這種特性,將一連串的浮點數總和運算拆分成多個運算。 例如題目中要相加10000次,但一定會出現誤差,因此只要再寫一個`add()`去做遞迴運算,把10000次分成多個小的組數,並且分別將他們計算的結果做相加就可以得到最後沒有誤差的結果,但這種方式需要較多記憶體以及不適合使用在第一次相加就會造成誤差的情況中。 在這篇[浮點數float累加誤差解決方式總結]()文章中,第四個方法也算是一種pairwise 的表現,但我認為可以搭配另外的函式去對數值做遞迴。 Pairwise summation: ```cpp float f = 0.1; float sum = 0; for( i=0; i<100; i++) { int sumEachBig=0; for(....k<400....) { int sumEachSmall=0; for(....j<100.....) sumEachSmall += f; sumEachBig+=sumEachSmall; } sum += sumEachBig; } ``` :::danger 缺乏誤差分析 :notes: jserv ::: ### 參考資料 [1] [浮點數的美麗與哀愁](https://champyen.blogspot.com/search/label/linux) [2] [Estimating Errors In Summing Arrays Of Floating Point Numbers](https://www.reidatcheson.com/statistics/floating%20point/error/2018/01/15/float-sum-errors.html) --- ## 測驗 `1` 考慮以下 C 程式的 `align4` 巨集的作用是,針對 4-byte alignment,找到給定地址的 round up alignment address。 ```cpp #include <stdio.h> #define align4(x) (((x) + K) & (-4)) int main(void) { int p = 0x1997; printf("align4(p) is %08x\n", align4(p)); return 0; } ``` 預期程式輸出 `align4(p) is 00001998` ==作答區== `K` = ? ### 作答想法 簡單來說,輸入的數字x 必須無條件進位,以4 byte 為一個進位的標準。主要是為了做對齊,因為一次擷取為4 byte ,如果一個int 分別位在兩個區段,這樣要擷取兩次,整體效能會較差,因此需要作對齊。 詳細的解說可以參考老師其他的課程內容如[你所不知道的C語言:記憶體管理、對齊及硬體特性](/@sysprog/BkuMDQ9K7),其中在data alignment 部份有提到完整的應用和解釋。 解題的部分,主要就是讓輸入的參數x 將該區段使用完畢,並且跳至下一區段,因此當x=0x1997時,K可以為1~3;但當x=0x1995時,K只能為3。取的是4-byte ,答案為`3`。 ### 延伸題目: 在 Linux 核心原始程式碼找出類似的 alignment 巨集並解釋其作用 - 使用關鍵字: linux kernel alignment code [bootlin](https://elixir.bootlin.com/linux/latest/ident/ALIGN) 這個網站可以透過關鍵字搜尋Linux Kernel Source Code ,因此針對ALIGN直接做搜尋,會搜尋出多個有使用 ALIGN Macro 的程式,這邊以`include/linux/kernel.h` 為例。 [`include/linux/kernel.h`:](https://elixir.bootlin.com/linux/latest/source/include/linux/kernel.h#L33) ```C=33 #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) #define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a)) #define __ALIGN_MASK(x, mask) __ALIGN_KERNEL_MASK((x), (mask)) #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) ``` 可以搭配這個[參考資料](http://charette.no-ip.com:81/programming/doxygen/netfilter/iptables_2include_2linux_2kernel_8h.html) ,搜尋__ALIGN_KERNEL_MASK 可以透過這個網站的解析該Macro 的內容。 ```C= #define __ALIGN_KERNEL(x,a) __ALIGN_KERNEL_MASK(x, (typedef(x))(a)-1) #define __ALIGN_KERNEL_MASK(x, mask) (((x)+(mask)) & ~(mask)) ``` 這個部分和測驗中的程式碼相似,測驗中,K 的數字為3,主要是為了以-4~(10)~對齊。如果將測驗的程式碼以kernel.h 中的程式碼呈現,則x為任意int 的變數,a 為-3 (signed int),測驗的主體部分則是 __ALIGN_KERNEL_MASK()。 ### 參考資料: - [1] [bootlin `include\linux\kernel.h`](https://elixir.bootlin.com/linux/latest/source/include/linux/kernel.h#L33) 主要參考的source code。 - [2] [linux 内核 AGLIN 巨集](http://blog.sina.com.cn/s/blog_1382bb9dd0102wcqw.html) 有簡單的講解ALIGN 巨集的功用,另外還有上下界對齊如 `alignment_down(a, size)` 和`alignment_up(a, size)` 。 - [3] [你所不知道的C語言:記憶體管理、對齊及硬體特性](https://hackmd.io/@sysprog/BkuMDQ9K7?type=view#data-alignment) 有完整的關於對齊的解說。 - [4] [kernel.h File Reference ](http://charette.no-ip.com:81/programming/doxygen/netfilter/iptables_2include_2linux_2kernel_8h.html) 比較完整的定義ALIGN Macro 。 - [5] [align macro kernel](https://stackoverflow.com/questions/13122846/align-macro-kernel) Stackoverflow 上其中一個關於ALIGN 對齊的問答,可以和[2] 擇一選看。 --- ## 測驗 `3` 考慮以下 C 程式碼: ```cpp #include <stdbool.h> bool func(unsigned int x) { return x && ((x & (~x + 1)) == x); } ``` 可改寫為以下等價的程式碼: ```cpp bool func(unsigned int x) { unsigned int unknown = 0; while (x && unknown <= 1) { if ((x & Z) == 1) unknown++; x >>= 1; } return (unknown == 1); } ``` 請補完程式。 ==作答區== `Z` = ? ### 作答想法 首先是第一個bitwise 程式的部份,`~x+1` 可以視為x 的補數,因此要思考x 和自己的補數作 AND運算之後還會等於自己的可能有哪些,答案只有 0~3 因此直接將答案帶進去可以發現只有當答案等於0, 1, 4時成立。但當答案等於0時會return False,其餘則是True。 再來是把三個數字分別帶入第二個程式碼的部份,第二個程式碼中,while 中主要在用來計算`unsigned int x` 轉成二進位後有幾個1,當超過2個會中止該loop,return 又只return 只有1個1的情況,因此可以判別這個函式主要用來處理輸入的x 是否只有1個1。所以`Z`可以簡單推論為1,用來計算最右邊的位元是否為1。 ### 延伸題目 延伸題目內容提到需要找出類似const-time的程式。 目前有找到下方兩個參考資料有類似的方法, [A Faster Approach to Count Set Bits in a 32-bit Integer](https://codingforspeed.com/a-faster-approach-to-count-set-bits-in-a-32-bit-integer/) : 主要用來計算有幾個1,和題目的應用有些相似。 - non const-time computing ```cpp inline int bitCount1(int i) { int count = 0; for (int j = 0; j < 32; j ++) { if (i < 0) count ++; i <<= 1; } return count; } ``` - const-time computing ```cpp inline int bitCount2(int i) { i = i - ((i >> 1) & 0x55555555); i = (i & 0x33333333) + ((i >> 2) & 0x33333333); i = (i + (i >> 4)) & 0x0f0f0f0f; i = i + (i >> 8); i = i + (i >> 16); return i & 0x3f; } ``` [Bitwise can avoid loops](https://blogs.sap.com/2012/04/09/bitwise-can-even-avoid-loops/) : 主要判斷,該數字是否為2的倍數。如果是則return True,如果否則 False。 - non const-time computing ```cpp int main() { int a = 256, rem,flag = 0; while (a > 1) { c = a % 2; if (c == 1) { flag = 1; break; } a = a / 2; } if (flag == 1) printf("Not Power of 2"); else printf("Power of 2"); return 0; } ``` - const-time computing ```cpp int main() { int a=256; if((a&(a-1)==0) printf("Power of 2"); else printf("Not Power of 2"); return 0; } ``` --- ##

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully