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
      • Invitee
    • Publish Note

      Publish Note

      Everyone on the web can find and read all notes of this public team.
      Once published, notes can be searched and viewed by anyone online.
      See published notes
      Please check the box to agree to the Community Guidelines.
    • 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
    • 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 Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Versions and GitHub Sync 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
Invitee
Publish Note

Publish Note

Everyone on the web can find and read all notes of this public team.
Once published, notes can be searched and viewed by anyone online.
See published notes
Please check the box to agree to the Community Guidelines.
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 webpage below. It will be converted to Markdown.

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 is not available.
Upgrade
All
  • All
  • Team
No template found.

Create custom 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

How to use Slide mode

API Docs

Edit in VSCode

Install browser extension

Get in Touch

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

No updates to save
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