2013年11月10日 星期日
分享治療背痛的有效方法
我做軟體這一行已經6年了,前幾年幾乎就是每天至少10小時的時間都坐在椅子上盯著電腦螢幕。大約在工作3年的時候,發現到自己在做轉體運動的時候,會發出咖咖的關節聲響,然後伴隨著壓迫肺臟發出的聲音。前胸的肋骨也常常不固定位置發出微微的不適感。過了一年後,胸椎的部分開始隱隱作痛,旋轉脖子開始有肌肉拉傷的那種痛感,甚至有一次搬嬰兒車都會瞬間痛到,可能壓迫到神經。於是我就去找了間復健診所(沒健保,每次800),做了有10次,但是也都沒有特殊改善。期間也有去陳潮宗針灸、推拿、喝水藥(4次),還好有實支實付否則真的虧大,因為真的沒用...。3年間主要去看中醫、推拿,也都沒有實際的改善。直到2013上半年,常常在落枕,受不了了就去google了一下,發現有骨科這種診所是可以治療這種傷害(以前天真以為骨科只看骨頭),於是就去了骨科看。醫師照了X光以後說頸椎間隙異常的小,可能有磨損到,於是也說了一些恐怖的後果。後來就安排去拉脖子,第一次拉的時候是9公斤的樣子,拉了很痛,因為那天剛好落枕才去骨科試試看。拉完幾乎無法坐起來,而且手有點麻麻,過了幾分鐘終於慢慢的坐起來。隨後就這樣做了好幾輪的拉脖子,隨著次數增加,來到了十多公斤,漸漸的那些背痛的症狀與落枕狀況都沒有發生了,我認定這就是治療我的背痛方法了!這簡直就是看到耶穌一樣有重生的感覺啊!因為很多報導都說背痛是跟心臟有關,或是影響到心臟導致心臟病,也有看過新聞報導曾經有一個人心臟病猝死,當時就貼著一個貼布在背後。現在已經拉到16公斤,一開始還是有點痛,不過做了中後段就不痛了,常常會睡著。所以我希望這個經驗也能夠讓跟我一樣是坐辦公室坐到背痛的人有一個方式可以去治療看看,不是說中醫無效,而是骨科也有類似的療程可以試試看。
2013年11月8日 星期五
關於效能改進,memory copy不是第一個要考量的
常常聽到有人說為了速度,要避免memory copy。但我在無論是維護性與效能上的考量,都覺得不是這麼回事。不要去追求pointer上的巧妙操作達到的zero copy,而忽略了平行處理上的可讀性。zero copy要作的地方是user與kernal space間的copy,而非同user space內的copy。後者幾乎是可以放在最後才去考量的。因此,我在評估系統設計對效能的衝擊有下面順序:
1. 減少 context switch:少用process,thread,少呼叫system call。使用 libev 這樣 event driven backend 來達到多工。而多處理器則使用 thread pool 的方式。
2. 增加 cache hit rate:在可攜的原始碼的原則下,採用那種記憶體也決定了cache的效率:
1. 優先使用 function 內部定義的空間,因為它是位於 stack,只要function return,SP 暫存器一減回去,就相當於被釋放了,是極為有效率的。
2. 如果要跨 function,就要訂好一個結構或是陣列,定義在 globol 的記憶體,因為它會位於固定的 .DATA 區段,當很密集在上面操作時,就很容易將資料保留在cache中。
3. 最後才考慮使用 malloc 系列函式,取得的空間會位於 heap 裡面。常常有一些作法是使用動態配置去配出一塊塊的記憶體,然後用 pointer 將它們連起來成為某一種資料結構。下面文章就是在講這種方式的問題在哪裡。
http://www.codeproject.com/Articles/340797/Number-crunching-Why-you-should-never-ever-EVER-us#TOC_DA_IV
使用heap取得的記憶體會東一塊西一塊,一下在這個 page 一下在另一個,就比較不容易 cache hit。反觀如果配置靜態記憶體加上event driven,將資料與運算集中起來一次在user space處理掉,就會很有效率。
如果資料結構真的很龐大、所指向的資料又不一定大小,該如何靜態?
這時候,一樣可以設計一個 warm cache 與 cold cache。將你的資料結構的"節點"放在靜態的array,並且用你最擅長的point連結他們,這是warm cache,因此走訪節點的時候就很容易在cache就搞定。當你找到節點後,再取出point指向的資料,這就是cold cache。
當你都檢視了用了多少 process、thread,IPC的資料傳輸有多少,資料結構是否容易cache hit。這些問題都已經釐清以後,再去探討資料搬移造成了多少負荷才能真的增加速度。
1. 減少 context switch:少用process,thread,少呼叫system call。使用 libev 這樣 event driven backend 來達到多工。而多處理器則使用 thread pool 的方式。
2. 增加 cache hit rate:在可攜的原始碼的原則下,採用那種記憶體也決定了cache的效率:
1. 優先使用 function 內部定義的空間,因為它是位於 stack,只要function return,SP 暫存器一減回去,就相當於被釋放了,是極為有效率的。
2. 如果要跨 function,就要訂好一個結構或是陣列,定義在 globol 的記憶體,因為它會位於固定的 .DATA 區段,當很密集在上面操作時,就很容易將資料保留在cache中。
3. 最後才考慮使用 malloc 系列函式,取得的空間會位於 heap 裡面。常常有一些作法是使用動態配置去配出一塊塊的記憶體,然後用 pointer 將它們連起來成為某一種資料結構。下面文章就是在講這種方式的問題在哪裡。
http://www.codeproject.com/Articles/340797/Number-crunching-Why-you-should-never-ever-EVER-us#TOC_DA_IV
使用heap取得的記憶體會東一塊西一塊,一下在這個 page 一下在另一個,就比較不容易 cache hit。反觀如果配置靜態記憶體加上event driven,將資料與運算集中起來一次在user space處理掉,就會很有效率。
如果資料結構真的很龐大、所指向的資料又不一定大小,該如何靜態?
這時候,一樣可以設計一個 warm cache 與 cold cache。將你的資料結構的"節點"放在靜態的array,並且用你最擅長的point連結他們,這是warm cache,因此走訪節點的時候就很容易在cache就搞定。當你找到節點後,再取出point指向的資料,這就是cold cache。
當你都檢視了用了多少 process、thread,IPC的資料傳輸有多少,資料結構是否容易cache hit。這些問題都已經釐清以後,再去探討資料搬移造成了多少負荷才能真的增加速度。
訂閱:
意見 (Atom)