2011年12月31日 星期六

Re: [爆卦] 通過不公義的土地徵收的立委名單

作者: skypons (低調) 看板: Gossiping
標題: Re: [爆卦] 通過不公義的土地徵收的立委名單
時間: Wed Dec 14 00:40:13 2011

※ 引述《fatfatman (勃起棒棒糖)》之銘言:
: 曹爾忠、廖國棟、孔文吉、林郁方、羅明才、
: 吳清池、趙麗雲、林德福、楊仁福、廖婉汝、
: 陳 杰、郭素春、林滄敏、侯彩鳳、林益世、
: 林鴻池、簡東明、鄭金玲、盧嘉辰、紀國棟、
: 費鴻泰、李復興、劉盛良、潘維剛、丁守中、
: 李明星、帥化民、江玲君、江義雄、賴士葆、
: 陳淑慧、蔡正元、鄭汝芬、徐少萍、洪秀柱、
: 蔣乃辛 和羅淑蕾。

參考網頁。

http://pnn.pts.org.tw/main/?p=36805

我很迅速地把比較版看完,濃縮式擷取重點條列如下:

土地徵收條例通過,為何為惡法? 用最簡單的方式比喻,讓更多人了解:


1. 政府想徵收就可以徵收,以市價作為徵收價,市價多少政府說的算。


2. 人民對於土地徵收無陳情、諮商管道。國家要你的的菜園,你沒第二句話"不"。


3. 被徵收者,必須符合:居住事實1年以上,切須符合中低收入戶,才有相關的安置計畫

。言下之意,不巧你非中低收入戶,一個月賺兩三萬,但政府要你滾,你就得滾,當遊民

政府也不會管你,因為"依法行政"。


4. 為了養地圖利,企業可假政府之手可以任意徵收農作用地,嚴重破壞農業自給比例的

平衡。


5. 對公益性與必要性的規定模糊,政府覺得重要且必要就得以徵收,有如大老爺挑小妾

。且亦已違反大法官釋憲:法規須詳盡、不厭其詳。


6. 徵收下限40%,且無限定徵收地地上權使用, 使政府可能以此漏洞斂財於民,以及因

下限過低,使徵收誘因無法被有效的制衡。





 結語: 很多人覺得立法院前的抗爭與我何干,但,假設今天一條路就要開到你家,政府

一紙公文要你滾蛋。你辛苦一輩子置房地產500萬在新北市,政府貼你200萬,要你限期搬

走。 你,不會生氣嗎?


PS. 本人完全非法律背景,完全只是個憤慨的鄉民,如有錯解、瑕疵,請多指教,感謝!





--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.62.92.80

2011年12月20日 星期二

用gdb解決core dumped

在FreeBSD上執行程式./a.out出錯了 Segmentation fault (core dumped)

產生了副檔名為core的檔案: a.out.core

別急著在程式碼中插入print再compile

先試試這個:

gdb a.out a.out.core

詳細用法:

進階gdb
multi-thread與multi-process除錯
http://www.study-area.org/cyril/opentools/opentools/x1265.html

基本gdb
http://www.study-area.org/cyril/opentools/opentools/x1253.html

2011年12月14日 星期三

Ghost in the Shell

攻殼機動隊 漫畫
1989-04
http://zh.wikipedia.org/wiki/%E6%94%BB%E6%AE%BC%E6%A9%9F%E5%8B%95%E9%9A%8A

攻殼機動隊 (電影)
1995-11
http://zh.wikipedia.org/wiki/%E6%94%BB%E6%AE%BC%E6%A9%9F%E5%8B%95%E9%9A%8A_(%E9%9B%BB%E5%BD%B1)

攻殼機動隊 STAND ALONE COMPLEX 電視動畫
2002-10
http://zh.wikipedia.org/wiki/%E6%94%BB%E6%AE%BC%E6%A9%9F%E5%8B%95%E9%9A%8A_STAND_ALONE_COMPLEX

攻殼機動隊 S.A.C. 2nd GIG 動畫影集
2004-01
http://zh.wikipedia.org/wiki/%E6%94%BB%E5%A3%B3%E6%9C%BA%E5%8A%A8%E9%98%9F_S.A.C._2nd_GIG

攻殼機動隊2 INNOCENCE (電影)
2004-03
http://zh.wikipedia.org/wiki/%E6%94%BB%E6%AE%BC%E6%A9%9F%E5%8B%95%E9%9A%8A2_INNOCENCE

攻殼機動隊 S.A.C. Solid State Society
2006-09
http://zh.wikipedia.org/wiki/%E6%94%BB%E5%A3%B3%E6%9C%BA%E5%8A%A8%E9%98%9F_S.A.C._Solid_State_Society

2011年12月11日 星期日

C++: static_cast, const_cast, reinterpret_cast, dynamic_cast

 作者  cppOrz (cppOrz)                                        看板  C_and_CPP
 標題  Re: [問題] static.const.reinterpret_cast和c-sty …
 時間  Sun Mar 12 23:26:23 2006
───────────────────────────────────────


Sorry, 有很多地方錯誤,不得不指出來。
熱心回答問題是好的,但是最好對內容有一定的把握,以免誤導。

這一篇介紹 C++ 的四個關鍵字: static_cast, const_cast, reinterpret_cast,
以及 dynamic_cast 的意義用法。

學習任何編程語言,只單純學習語法是不夠的,要適當的運用某種語言機制,最好
要先知道該機制存在的目的,和什麼狀況下會需要用到它,否則還不如不要使用。


※ 引述《godfat (godfat 真常)》之銘言:
: 靜態轉型,簡單地說就是強制轉型,
: 只是不合理的轉型 compiler 會告訴你不能這樣轉
: 例如兩個毫無關聯的物件
: class A{};
: class B{};
: A a;
: static_cast<B>(a); // error

static_cast 用於「相關型別」之間的轉換,其目的是讓編譯器知道,
程序員是「有意識」的進行轉換動作,並非不小心打錯。例如:

float f = 123.456f;

int i = f; // 把 float 轉為 int,編譯器一般會給警告
int v = static_cast<int>(f); // 用 static_cast 通知編譯器,設計意途確實如此


此外 static_cast 也可用於繼承體系內的 downcast,例如:

struct B { void f(); };
struct D : B { void g(); } d;

B &b = d;
...

b.f(); // ok
b.g(); // 錯誤,b 是 reference to B 物件

static_cast<D&>(b).g(); // ok, 因為程序員知道 b 確實是參照某個 D 物件


: : const_cast
: 單純去掉物件的常數性 和/或 volatile 性

這裏是對的。

: int const i = 10;
: i = 5; // error
: const_cast<int&>(i) = 5; // ok
: (這邊我不太確定是不是這樣寫,很少用)
: (總之觀念是這樣)

舉例有誤。

const_cast 只是把常數性去掉,目的是方便設計,但是企圖通過 const_cast
修改一個 const 物件,其結果未定義(視實作環境是否對該 const 物件採取
保護措施)。

至於 const_cast 使用的時機,通常是為了在不修改既有模組(例如沒有 source
code 的程式庫)的情況下,解決兩個模組之間 const-correctness 不相容的問題
(通常是不能改的那個模組,其設計不夠周延)。例如:

struct C { void f(); }; // 假設 C 是一個既存的模組(不能修改)

void foo(C const &c) // foo 是自行設計的模組,c 物件只作為輸入,不會被更動
{
  ...

  c.f(); // 由於 c 是 referece to const C 物件,但 C::f 並未被設計為
         // const,因此這樣寫是不成立的。(編譯器會給錯誤或至少警告)

  const_cast<C&>(c).f(); // ok, 用 const_cast 去掉 c 的常數性
}

: : reinterpret_cast
: 強迫 compiler 把輸入型別視為欲轉換的型別
: 這個不太好解釋…總之就是暴力轉型就對了 XD
: 直接把該記憶體位置的資料視為欲轉換的型別來看待

reinterpret_cast 幾乎等於暴力轉型(指 C-style 轉型),但不能去掉物件
的常數性(也就是還不夠暴力)。它用來處理任意型別之間的轉換,通常是為
了爭取運算或儲存空間的效率時,所採取的低階操作。例如:

int IP_Addr = 0;
char *p = reinterpret_cast<char*>(&IP_Addr); // 轉型為 char *,以便於
                                             // 以 Byte 為單位來處理
p[0] = 192;
p[1] = 168;
p[2] = 0;
p[3] = 1;

傳統的 C-style 轉型相當於 static_cast, const_cast, reinterpret_cast
三合一(也就是暴力加三級)。


: 你漏了 dynamic_cast<>
: 這跟 static_cast<> 有些類似

dynamic_cast 和 static_cast 無關。

: dynamic_cast<> 只能對於具有多形性型別轉型,
: 也就是他至少得要有一個 virtual function

這裏是對的。dynamic_cast 是 RTTI 的一部份,它用來檢測一個多型基底
類別的 pointer 或 reference 所參照物件的實際型別。例如:

struct B1 { virtual void f() = 0; };
struct D1 { void f(); };
struct X : D1
{
  void f();
  void g();
};

void foo(B1 *b1) // foo 模組並不知道 b1 所參照物件的實際型別
{
  if (dynamic_cast<D1*>(b1)) // 如果 b1 參照的是 D1 物件
  {
    b1->f();
  }
  else if (D1 *d1 = dynamic_cast<X*>(b1)) // 如果 b1 參照的是 X 物件
  {
    d1->g();
  }
  else
  {
    ...
  }
}

此例中,dynamic_cast 的用法也是所謂的 downcast,但和 static_cast
不同的是,前者用於偵測未知多型物件的實際型別,而後者用於對已知物件
(可以是多型物件或普通物件)的轉型。

可以看出,B1, D1, X 的繼承體系設計並不是很理想,因為在這種情況下,應該
直接利用 virtual function 的動態多型機制,而非依賴 dynamic_cast 偵測物
件的型別。例如:

struct B2
{
  virtual void f() = 0;
  virtual void g() = 0;
};

struct D2 : B2
{
  void f();
  void g();
} d2;

struct Y : D2
{
  void f();
  void g();
} y;

void foo()
{
  B2 *b2 = &d2; // b2 參照 D2 物件
  b2->g(); // 實際上會執行 D2::g,不必依賴 dynamic_cast

  b2 = &y; // 換一下,改參照 Y 物件
  b2->g(); // 實際上會執行 Y::g
}

顯然,B2, D2, Y 的設計比較合理。事實上,如果所有的模組都是自行設計,
dynamic_cast 是多餘的。但它之所以存在,其目的就是為了解決「既存模組
」不能修改的問題。(最常見的例子,就是缺乏源代碼的程式庫)

前面的例子中,如果 B1, D1 兩模組不能修改,為了新擴充 X 模組,又要和
舊模組相容,dynamic_cast 在此情況下就能派上用場(反過來說,如果沒有
dynamic_cast,問題就會變得很麻煩,而且各種替代方案都不太安全);但
如果完全是可自行控制的設計,就應該儘量遵循 B2, D2, Y 的方式來組織。


以上是 dynamic_cast 的功能中,downcast 的部份。另外,由於 C++ 支援
多重繼承的機制,dynamic_cast 亦可用於 crosscast(橫向轉型),例如:

struct Z : B1, B2 // 多重繼承
{
  void f();
  void g();
} z;

void foo()
{
  B1 *b1 = &z;
  B2 *b2 = dynamic_cast<B2*>(b1); // crosscast
}

這個例子可以用來說明,dynamic_cast 實際上的動作是「型別檢測」,而非
僅僅是「轉型」,後者只是它輸出的結果。此例中,b1 表面上是 (B1 *),但
它實際上參照的是 Z 物件,因此 dynamic_cast 偵測的結果,就是它可以順
利轉為 (B2 *) 。


: struct Base{virtual ~Base(){}};
: struct Derived: public Base{};
: Base pb = new Derived;
: Derived pd = dynamic_cast<Derived*>(pb);
: 如果 pb 真的是指向 Derived, 則 dynamic_cast<> 傳回 pb 的地址
: 否的話,pd 為 NULL
: boost 有提供 polymorphic_cast<>, 用處同 dynamic_cast<>
: 差別在於錯誤時不是傳回 NULL, 而是丟出 std::bad_cast
: polymorphic_downcast<> 則是專門用來在已知必然成功的 downcast
: 這種時候內建的 static_cast<> 和 dynamic_cast<> 其實都可以用,
: 只是 static_cast<> 沒有錯誤檢查,dynamic_cast<> 效率太差
: polymorphic_downcast<> 則使用 assert(); 來檢查是否成功
: http://www.boost.org/libs/conversion/cast.htm
: : c-style cast
: 等同於上面全部...
: 在 C++ 中替他們分類,避免造成混淆
: 不過對初學者來說的話這麼多才是混淆吧,我猜 :p
(下略)

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 59.120.214.120
推 godfat:感謝指導,雖然我覺得跟我講的沒啥衝突 XD 大概是太隨便了   03/13 01:44
※ 編輯: cppOrz          來自: 59.120.214.120       (03/13 04:50)
※ crazying:轉錄至看板 NTUGIEE_EDA                                 03/13 11:58
推 abovelight:推一個~了解更深入了                                  03/14 18:16

2011年12月7日 星期三

車禍 2011-11-25

http://www.youtube.com/watch?v=Vv5UozmCMCU
http://www.youtube.com/watch?v=FoNRoNrfvIo&feature=youtu.be&t=1m35s

有毒合法--廢棄爐渣的檢測魔術

http://blog.yam.com/munch/article/25240764

摘要:
講白一點,當爐渣還未入土,一塊塊拿去測驗,結果是合法無毒,於是放行埋地,當爐渣碎裂成土污染釋出,再拿化成土的爐渣去測驗,變成有毒致命人畜勿近,於是造成現今這種事前不阻擋,事後才花費上億金錢整治的荒謬。

2011年12月4日 星期日

matrix67

趣題

识别被挤压的数字图像(蛮有趣)
http://www.cnblogs.com/humtong/archive/2008/02/24/1079757.html

也说Pizza问题:分享几个漂亮的证明
http://www.matrix67.com/blog/archives/2946#more-2946

有趣的益智題

趣题:老鼠与毒药问题的推广
http://www.matrix67.com/blog/archives/4361#more-4361

经典智力题:自行车往哪个方向行驶?
http://www.matrix67.com/blog/archives/2817#more-2817

用一张日落照片估算出地球的半径
http://www.matrix67.com/blog/archives/3331#more-3331

100个囚犯和灯泡的那些事儿(上)
http://www.matrix67.com/blog/archives/3618

O3 ·7 ·5 ·5 ·4 ·7 ·6 ·6 ·7 ·?
http://www.matrix67.com/blog/archives/610#more-610

寻找1/5 + 1/25 + 1/125 + .. = 1/4的图形证明
http://www.matrix67.com/blog/archives/tag/%E5%9B%BE%E5%BD%A2/page/4
网友来信:关于几何级数的图形证明
http://www.matrix67.com/blog/archives/2289

密码学协议举例(一):带有防欺骗的承诺
http://www.matrix67.com/blog/archives/1230


有趣的圖

Menger海绵体的斜截面是什么样子的
http://www.matrix67.com/blog/archives/433

几个令人惊叹的函数图像
http://www.matrix67.com/blog/archives/4447#more-4447

Tupper自我指涉公式:图象里竟然包含式子本身
http://www.matrix67.com/blog/archives/301

OIer好帮手:graphviz功能演示
http://www.matrix67.com/blog/archives/160

最牛的图纸:Escher网格
http://www.matrix67.com/blog/archives/1103

一个只有数字9的时钟
http://www.matrix67.com/blog/archives/295

神奇的分形艺术(三):Sierpinski三角形
http://www.matrix67.com/blog/archives/280
Sierpinski三角形与Hanoi塔

神奇的分形艺术(二):一条连续的曲线可以填满整个平面
http://www.matrix67.com/blog/archives/249

2011年11月28日 星期一

死神的手指

鄭明典
「死神的手指」影片說明
這是英國BBC製作的短片,很值得多看幾次!
海水結冰會把水中的鹽分逼出,在海冰成長的過程中,部分被逼出的海鹽會被包覆在冰層中,以極濃的液態鹹水狀態存在,這種鹹水溫度低、密度高。
因為重力的作用,過冷的鹹水最後會從冰層底下流出,因為它比海水重而且冷,流出的過程中讓周圍直接接觸的海水結冰,逐漸形成冰層下的「冰管」,有時冰管可以延伸到海底,結果過冷的鹹水在海底散開來,讓海底相對溫暖的海水瞬間結凍,海底生物來不及走避就會被凍成標本!
因為冰管很像手指,他到達的海底常有生物大量被凍死,所以稱為「死神的手指」!
底下的聯結是BBC攝影團隊在南極冰層底下實地拍攝製作的短片,這是首次完整呈現「死神的手指」發展過程的紀錄片!
http://youtu.be/LMhBuSBemRk

臺61線相片

https://plus.google.com/u/0/photos/106772525394348666482/albums/5678475144528989729?hl=zh-TW

2011年11月15日 星期二

CHENGLAP文章集錦

CHENGLAP文章集錦
http://chenglap-ptt.blogspot.com/

民主失竊的故事 The Story of Citizens United v. FEC 中文字幕

民主失竊的故事 The Story of Citizens United v. FEC 中文字幕
http://www.youtube.com/watch?v=A4x7MFZ4BXg

讓 Facebook 速度飆升的秘密武器:Big Pipe 網頁流水線技術

讓 Facebook 速度飆升的秘密武器:Big Pipe 網頁流水線技術

銀行界不能說的祕密 面板業大到不能倒

銀行界不能說的祕密 面板業大到不能倒
http://news.chinatimes.com/tech/12050905/122011111400096.html

布雷斯悖論 Braess's paradox

布雷斯悖論 Braess's paradox
http://zh.wikipedia.org/wiki/%E5%B8%83%E9%9B%B7%E6%96%AF%E6%82%96%E8%AE%BA

2011年11月8日 星期二

strtol

http://www.cplusplus.com/reference/clibrary/cstdlib/strtol/


Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* strtol example */
#include 
#include 

int main ()
{
  char szNumbers[] = "2001 60c0c0 -1101110100110100100000 0x6fffff";
  char * pEnd;
  long int li1, li2, li3, li4;
  li1 = strtol (szNumbers,&pEnd,10);
  li2 = strtol (pEnd,&pEnd,16);
  li3 = strtol (pEnd,&pEnd,2);
  li4 = strtol (pEnd,NULL,0);
  printf ("The decimal equivalents are: %ld, %ld, %ld and %ld.\n", li1, li2, li3, li4);
  return 0;
}

icosahedral photonic quasicrystal and diffraction patterns of decagonal quasicrystals

http://pbircher.blogspot.com/2009/11/icosahedral-photonic-quasicrystal.html

2011年11月6日 星期日

慘遭助教修理的一道程式習題 冼鏡光

慘遭助教修理的一道程式習題 冼鏡光
http://blog.dcview.com/article.php?a=ADgAZgJlVGQ%3D

Fortran筆記2

http://www.chem.ucl.ac.uk/resources/history/people/vanmourik/images/Fortran%2095-manual.pdf
In C:


void foo(void)
{
    static int a = 5;
    int const b = 6;
}


In Fortran90/95:


SUBROUTINE FOO()
IMPLICIT NONE
INTEGER, SAVE :: A = 5
INTEGER, PARAMETER :: B = 5
END





Array assignment statements



coords(1) = 3.5 
block(3,2) = 7 


do i = 1,3 
     coords(i) = 0.0 
 end do 


coords = (/ 1.3, 5.6, 0.0 /)



coords = (/ (2.0*i, i = 1, 3) /)  ! yields (2.0, 4.0, 6.0) 
odd_ints = (/ (i, i = 1, 10, 2) /)  ! yields (1, 3, 5, 7, 9) 
integer, dimension (8), parameter :: primes = (/ 1, 2, 3, 7, 11, 13, 17, 19 /) 



For example, a two-dimensional array b(2,3) can be added to the array section a(2:3, 1:3) 
of the array a of the previous section.  If the array c is an array of dimension (2,3), then 
the expression 
c = a(2:3,1:3) + b 
causes the elements of the array c to have the following values: 
 c(1,1) = a(2,1) + b(1,1) 
 c(2,1) = a(3,1) + b(2,1) 
 c(1,2) = a(2,2) + b(1,2) 
 c(2,2) = a(3,2) + b(2,2) 
 c(1,3) = a(2,3) + b(1,3) 
 c(2,3) = a(3,3) + b(2,3)

The same can be achieved by using a do loop: 
 do i = 1, 3 
     do j = 1, 2 
         c(j,i) = a(j+1,i) + b(j,i) 
     end do 
 end do 
But the expression c = a(2:3,1:3) + b is clearly more concise.   

給老師與同學:作業系統投影片下載 冼鏡光

給老師與同學:作業系統投影片下載 冼鏡光
http://blog.dcview.com/article.php?a=Az0CZlc3AzcGYQ%3D%3D

台灣史上最大貪污 正悄悄進行(張宏林)

台灣史上最大貪污 正悄悄進行(張宏林)
http://tw.nextmedia.com/applenews/article/art_id/33787628/IssueID/20111103

2011年11月5日 星期六

Fortran 筆記

Fortran 77


Data Type


IMPLICIT NONE


INTEGER
[sign][[base]#]constant
1. sign: "+" or "-",省略代表正
2. [[base]#]省略,表十進制。[base]省略,#保留,表16進制。
base:2~36
2#11011
36#2DM8F


REAL
-.28E2
.54D+3 (倍精度)


DOUBLE PRECISION


COMPLEX


(REAL,REAL)


LOGICAL


.TRUE.
.FALSE.


CHARACTER


CHARACTER A
CHARACTER B*10
CHARACTER*20 C*10, D
CHARACTER*(2*3) E
A 1
B 10
C 10
D 20
E 6


PARAMETER( 變數名稱=常數[,變數名稱=常數...] )




Fortran 90/95


INTEGER*1
INTEGER*2
INTEGER*4
INTEGER(4)
INTEGER(KIND=4)


REAL (4 btyes, 單精度)
REAL*4 (4 btyes, 單精度)
ERAL*8 (8 bytes, 雙精度)

2011年11月2日 星期三

菱形

原理:
n=3


  * 
 * * 
* * * 
 * * 
  * 


*  =


       j
    0 1 2
   2  
   1 
 i 0
  -1 
  -2  



#include
int main(void)
{
    int n, i, j;
    scanf( "%d", &n);
    for( i = n-1; i >= -n+1; --i )
    {
        for( j = 0; j <= n-1; ++j )
        {
            if( i <= j && -i <= j )
                printf("* ");
            else
                printf(" ");
        }
        printf("\n");
    }
    return 0;
}

Javascript程序员嘴最脏??

Javascript程序员嘴最脏??
http://coolshell.cn/articles/1850.html

半導體代工的故事

半導體代工的故事
http://mhperng.blogspot.com/2011/10/blog-post_30.html
http://mhperng.blogspot.com/2011/10/blog-post_9962.html
http://mhperng.blogspot.com/2011/10/blog-post_1192.html

2011年10月26日 星期三

用 PuTTY 的 SSH Tunnel 上 BBS

用 PuTTY 的 SSH Tunnel 上 BBS
http://blog.xuite.net/vexed/tech/14718287

用 PuTTY 的 SSH Tunnel 瀏覽網頁
http://blog.xuite.net/vexed/tech/22157888

2011年10月24日 星期一

C Variadic functions stdarg.h 不定參數

C Variadic functions stdarg.h
http://zh.wikipedia.org/wiki/Stdarg.h

我的移除要求

https://www.google.com/webmasters/tools/removals?pli=1
我的移除要求
您可以使用這個頁面要求我們將網頁或網站從 Google 的搜尋結果中移除 (不一定所有要求都會通過核准。詳細原因。)。
使用此工具將特定內容從 Google 的搜尋結果中移除。
您沒有未完成的移除要求。

2011年10月23日 星期日

Recursive

http://www.programmer-club.com/pc2020v5/Forum/ShowSameTitleN.asp?URL=N&board_pc2020=general&id=2830
作者 : chiuinan2(青衫)

(1) recursive algorithm:

Procedure HANOI(A,B,C,n) // 將n個環從A移到B //
    if n<=0 then 
        print("error")
    else if n=1 then 
        print(A,"→",B)
    else
       [ call HANOI(A,C,B,n-1); 
         print(A,"→",B);
         call HANOI(C,B,A,n-1) ]
end

設計的主要觀念為:
    1.將A柱中前n-1個環搬到C柱中暫置。(呼叫自己)
    2.將A柱中剩下最大的環搬到B柱中。
    3.將C柱中的n-1個環搬到B柱中。(呼叫自己)

(2)將recursive改成non-recursive的做法有很多種。如果已經知道recursive algorithm的話,最正統的方法便是直接將它化成non-recursive的形式。由recursive algorithm化成non-recursive algorithm的方法如下:

  1.在程式開頭處標上一個label。
  2.在每個呼叫自己的敘述的下一個敘述前,各標上一個label。
  3.把每個呼叫自己的敘述代換成一個將目前狀態push到stack的敘述,以及將程式參數改變的敘述,然後跳回程式的開頭。
  4.將每個返回敘述變成檢查stack的敘述,只有在stack為空時才能返回,否則必須pop出以前的狀態,然後跳到應返回的位置繼續執行。

上述的方法其實是在模擬程序遞迴呼叫的方式,label的記錄則是要得知其返回位址。因此本題的non-recursive algorithm便可以化成:

Procedure HANOI(A,B,C,n) // 將n個環從A移到B //
step 1: 
    if n<=0 then 
        print("error")
    else if n=1 then 
        print(A,"→",B)
    else
        [ push(A,B,C,n-1,2);
          (A,B,C,n)←(A,C,B,n-1);
          goto step 1;
step 2:
          print(A,"→",B);
          push(A,B,C,n-1,3);
          (A,B,C,n)←(C,B,A,n-1);
          goto step 1; ]
step 3: 
    if stack not empty then
        [ pop(A,B,C,n,ret_step);
          goto ret_step ]
end

這個方法所得出的algorithm雖然不是最佳的,但是卻保證一定正確。當然您也可以利用程式技巧將它化簡成沒有label的結構化程式。另外一種方式是要靠靈感的,可說是可遇而不可求。例如上述algorithm,其實可以寫成:

Procedure HANOI(A,B,C,n) // 將n個環從A移到B //
step 1:
    if n<=0 then
        print("error")
    else if n=1 then
        print(A,"→",B)
    else
        [ Push(C,B,A,n-1);
          Push(A,B,C,1);
          Push(A,C,B,n-1) ]
    if stack not empty then
        [ pop(A,B,C,n);
          goto step 1 ]
end

使用三個push敘述來模擬三次搬運,相當簡潔。這是從觀察它的呼叫方式和stack的關係所發覺的,並無規則可循。雖然這個algorithm相當簡潔,但是執行速度並不是最好的。主要的原因是在於模擬recursice call的stack push和pop次數太多,因而減低了執行的速度。如果我們所要求的是速度的話,則必須儘量不要用stack的結構來模擬,應該從分析該問題non-recursive關係著手。這種過程一般都相當冗煩,而且不一定能夠做得到。這裡我們只列舉別人研究的成果供讀者參考,並做為以後您將來寫程式時的一個目標。Hanoi塔問題的non-recursive關係如下:

另類行列式計算法——Chiò 演算法

另類行列式計算法——Chiò 演算法
http://ccjou.twbbs.org/blog/?p=4513

2011年10月22日 星期六

大陸溫州亂象之我見

大陸溫州亂象之我見
http://e-big.blogspot.com/2011/10/blog-post_17.html

[小惡魔的電腦教室] 電腦達人養成計劃,正式啟動!

[小惡魔的電腦教室] 電腦達人養成計劃,正式啟動!
http://www.mobile01.com/newsdetail.php?id=3527

2011年諾貝爾化學獎簡介

2011年諾貝爾化學獎簡介
http://www.ch.ntu.edu.tw/nobel/nobel100.htm

Bossa Nova 巴薩諾瓦

Bossa Nova
巴薩諾瓦
http://zh.wikipedia.org/wiki/%E5%B7%B4%E8%96%A9%E8%AB%BE%E7%93%A6

什麼蟲子咬我?

什麼蟲子咬我?
http://www.youth.com.tw/db/epaper/es002002/eb2568.htm

程式語言排名

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

2011年10月9日 星期日

從科學園區論全民受害的國家暴力

從科學園區論全民受害的國家暴力
http://mhperng.blogspot.com/2011/09/blog-post_2631.html

什麼是錢!!?

什麼是錢!!?
http://accrcw75.pixnet.net/blog/post/38094608


什麼是錢?

錢就是欠條。不管是黃金白銀,還是紙鈔,還是電子幣,本質都是欠條。黃金白銀、紙幣、電子幣的地位都是平等的,“金本位貨幣”理論是錯誤的。

假設世界上只有兩家人,老美兩口子和老華兩口子,開始他們兩家各幹各的,自給自足。一天,老美捉了4條魚,老華逮了8只鳥,老美想嘗嘗鳥味,老華想品品魚鮮,他們就交換了,老美用2條魚換了老華的4只鳥。以後他們常常這樣交換。

有一天,老美懶了,沒去捉魚,在家睡了一天。晚上,老華逮鳥回家,老美沒東西吃,就找老華借鳥吃。老美找一張樹皮,在上面寫上:2條魚。到老華家後,對老 華說:“我來換你4只鳥。不過,我今天生病了,沒能去捉魚,我給你打2條魚的欠條。”老華說:“這好說。”把欠條收下,把4只鳥給了老美。老美回去吃得美 滋滋的。

老美嘗到了這個甜頭,第二天又在家睡一天,晚上又拿2條魚的欠條去換了4只鳥。交換完畢,老美對老華說:“以後欠條上就不寫2條魚了,這欠條是我老美打的,以後就寫2美元吧。”老華欣然同意。以後欠條就用美元表示,如此日復一日。

按照商品交換的原則來說,商品交換應該是物物交換,商品換商品,而不是錢和物的交換。老美拿錢換了老華的鳥,老華得到錢,這不是商品交換的全過程,只是半 個過程。

老華手裡有老美的錢,就說明老美還欠老華的魚。所以,錢的本質就是欠條。等老華拿錢買了老美的魚後,商品交換的整個過程才結束。這個過程就是老美 用魚換了老華的鳥。

如果老華始終不用錢去換老美的鳥,那麼老美就占了大便宜了,白吃白喝老華的。可是,這裡,老美就設法始終不讓老華拿錢到他那裡兌換實 物。

日子長了,老華手裡積攢的錢有一大堆。老美害怕老華來兌換實物,就對老華說:“現在我們之間的交易,你是順差,順差對你是非常有利的,你要保持下去。”老華聽了很高興,就捨不得兌換實物了。老華就沒想起來問一問:“你是逆差,既然逆差不利,你為什麼要始終保持逆差呢?”

又過一天,老美覺得4只鳥不夠吃的,就寫了3美元,到老華家買了6只鳥。老美一天有6只鳥吃,老華反而只有2只鳥吃,餓得饑腸轆轆。但是一想到手裡有那麼多的錢,到老美家可以買很多很多的東西,夠自己養老的了,也就覺得值了。

以前,秦國利用其權威,經常為各國培養奸賊。外國的王公貴族到秦國去,秦國就教育他們:“以後只要秦國和你們的國家打仗,你們就割地,這對你們國家是最有 利的。”這些王公貴族,回到自己的國家後,因為是從秦國留學回去的,滿腹經綸,都被委任要職。

後來,只要秦國的大兵一壓,或者一封討伐信一到,這些國家就 立即割地。如今,美國的這種“順差有利”的理論被各國的留學生帶到世界,也就成了主流經濟學理論,美國靠印錢到各國買東西,各國都像守寶貝一樣守著美元, 捨不得花,美國暗裡得意死了。

又過了很長一段時間,老華發現老美給他的一些錢被蟲蛀了,想到老美家把這些欠條兌換成實物。老美對他說:“這些錢都是財富,你怎麼能輕易花掉呢?你太奢侈 了。

你不要擔心我兌換不起你,我富裕的很,你看我吃的喝的,哪樣不比你好?”邊說邊指著屋裡的一口袋一口袋的鳥肉乾說:“你看我有這麼多的財富,你還擔心 什麼?我完全能兌換得起你,你不要擔心,我拿我的人格發誓,我絕對不違約。

可是你有什麼,你就是個窮光蛋,天天餓得直打晃,我看著都可憐。俗話說,越窮越 賴,我倒擔心你的信譽呢。”老美說完,忽然感到說得不好,又立即改口說道:“當然啦,你只是表面上窮,實際上你非常富裕,你有那麼多的外匯儲備。

你看我有什麼,欠一屁股債。我倒感覺你對我的天下第一富的地位有嚴重威脅呢。”老華被他說得,如同一口喝了二兩老白乾,頓時覺得暈暈忽忽的。

老美又說道:“這充分 說明你這條路走對了。今後你還要繼續走下去,我們之間的貿易是互惠互利的。我們要共同富裕。”老華感激萬分,忙向老美表態:“您放心,我是個負責任的人, 絕對不失信!”

老美又指著老華手裡的錢說道:“既然這些錢被蟲蛀了,我就給你重新寫個債券吧。算是我借你的債,付給你優厚的利息,一年後還錢。”老華一 聽,這個合算,就換了一張債券回去。他們的交易又正常繼續下去。

終於有一天,老華有點醒悟了。他想:“老美這個傢伙天天什麼活都不幹,吃的喝的,全都是我的,比我過得還滋潤,我得到的只不過是些樹皮。而他總是想盡一切辦法,編出各種理論不讓我兌換實物,如果不能兌換,就只能當柴火燒。算了,以後就不和他交易了。”

晚上,老美又拿3美元去買鳥。老華不給他。老美就說:“如果你不賣給我,我就得餓死,那麼你手裡的美元和債券就全廢了。你要知道,現在救我就是救你自己。”老華聽了,不得已,還得和他交易。

究竟和老美還繼續交易不交易?老華愁死了,但是在他妻子面前還得裝作很英明的樣子。

轉眼一年過去了,老華的妻子翻出老美的那張債券,催老華去討債。還塞給老華一大抱美元,讓他順便到老美家多買點東西。老華怕減少外匯儲備,不想買東西,兩 口子為此事爭吵起來。老華的妻子嚷道:“不買東西,留這些美元有什麼屁用?今後不准你再要他的美元,也不准你再要他的債券!”

聲音傳到隔壁,老美嚇死了。對他妻子說:“我倒不怕他們來討債,我造錢還他就是了,要多少有多少。說實話,我根本就不需要向他們借債,不管買什麼,我直接 造錢付帳就行。其實,不管是我發出去的債券,還是美元,本質都是債券,都表明我欠人家的實物。

而我之所以要向他們借債,就是演戲,讓他們知道我對造錢很慎 重,不輕易造錢,我也不造錢買東西,以保持他們對美元的信任。我最怕的就是他們懷疑我亂造錢,造錢買東西,不信任美元,不接受美元。

其次我怕的是他們拿美元來換實物。這樣要把我們掏空還不說,我們還不能白占他們的便宜了。我們得想個辦法,讓他們繼續相信和接受美元,還不能讓他們來兌換實物。”

於是兩口子就嘀咕了一陣子,然後大聲吵起架來。老美的妻子大聲罵老美:“你這個飯桶,就知道吃吃喝喝,我讓你節省開支你也不節省,欠的都是債,拿什麼還 哪,我的老天爺呀,這個日子我不過了,我得上吊去!”

老美也大聲罵他的妻子:“你這個掃帚星,就知道怨我,你天天塗脂抹粉,穿紅戴綠,我讓你節省開支你聽 了嗎?你就知道讓我天天去借債,我上哪借去?你看人老華家的,那才叫會管家,人家多富裕,錢都多得發黴了。攤上你這個女人,我算倒八輩子的黴了。我也不活 了,我也得上吊去!”

隔壁老華兩口子聽得一清二楚,都想:“你們千萬不能死,你們死了,我們問誰要債去!你們要是缺錢花,就趕緊來借吧,借多少都有,絕對不限制,救你們就是救 我們自己。”老華想完,就對妻子說:“他們太可憐了,不能讓他們就這樣倒下。他們不好意思來借債,我們就主動送上去吧。 家裡還有一隻鳥,也送給他們吧。”老華的妻子連連點頭。

於是兩口子抱起一大抱美元和家裡僅剩的一隻鳥,到老美家去,對他們說:“送給你們應應急吧。”說完兩口子轉身就走了。

老美兩口子在後面,望著他們的背影,樂翻了天。

老美說:“這樣的傻瓜窮死活該!

簡報技巧小整理

簡報技巧小整理
http://funding101.blogspot.com/2011/01/blog-post.html

2011年10月7日 星期五

〈容忍與自由〉胡適

〈容忍與自由〉胡適

節錄部份:

《王制》(《禮記》的一篇)

...

我在那時候也完全沒有想想《王制》那句話的歷史意義。那一段《王制》的全文是這樣的:

『析言破律,亂名改作,執左道以亂政,殺。作淫聲異服奇技奇器以疑眾,殺。行偽而堅,言偽而辯,學非而博,順非而澤以疑眾,殺。假於鬼神時日卜筮以疑眾,殺。此四誅者,不以聽。』

我在五十年前,完全沒有懂得這一段話的「誅」正是中國專制政體之下禁止新思想、新學術、新信仰、新藝術的經典的根據。我在那時候抱著「破除迷信」的熱心,所以擁護那「四誅」之中的第四誅:「假於鬼神時日蔔筮以疑眾,殺。」我當時完全沒有夢到第四誅的「假於鬼神……以疑眾」和第一誅的「執左道以亂政」的兩條罪名都可以用來摧殘宗教信仰的自由。我當時也完全沒有注意到鄭玄注裏用了公輸般作「奇技異器」的例子;更沒有注意到孔穎達《正義》裏舉了「孔子為魯司寇七日而誅少正卯」的例子來解釋「行偽而堅,言偽而辯,學非而博,順非而澤以疑眾,殺」。故第二誅可以用來禁絕藝術創作的自由,也可以用來「殺」許多發明「奇技異器」的科學家。故第三誅可以用來摧殘思想的自由,言論的自由,著作出版的自由。

孩子問:「什麼是麒麟?」Giraffe嗎?

孩子問:「什麼是麒麟?」Giraffe嗎?
http://drspieler.blogspot.com/2009/09/giraffe.html

C與Fortran誰快,我該用哪種

關於Fortran較快的論點:
http://stackoverflow.com/questions/146159/is-fortran-faster-than-c

Fortran不允許兩個Pointer指向同一記憶體,C允許,所以C須重複load同一塊記憶體
除非C加上keyword returict:
http://en.wikipedia.org/wiki/Restrict

但只有C99支援
且還有其他因素使Fortran快於C,但其他因素是什麼?

 作者  yoco315 (眠月)                                         看板  C_and_CPP
 標題  Re: [問題] 為何公認fortran速度略快於C ?
 時間  Fri May  1 02:38:34 2009
───────────────────────────────────────


※ 引述《Carbontube (碳管)》之銘言:
: 大體上,就多數人認知,C與Fortran速度是有差的
:   小弟實在想不透這點,為何fortran可以比較快。


這邊有解釋
http://stackoverflow.com/questions/146159/is-fortran-faster-than-c


簡單來說就是 fortran 可以作一些 C 沒辦法(自動)做的最佳化
至於為什麼沒辦法自動作上面這篇跟下面 [1] 都有講
但是我們還是可以提示 compiler 作這個最佳化,看 [1]


這邊有兩個 C 的加速手段
[1] http://tinyurl.com/dygwpb __restrict__
[2] http://tinyurl.com/d55t9f __builtin_prefetch


只用上 [1] 的話大概打平手或是小贏,
[1] 跟 [2] 都用上的話,C 就贏了,我沒試過,只是合理推論
不過 [2] 不是標準,[1] 也只是 C99 的標準,C++ 沒的用
(雖然說還是有 extension 支援)


--
To iterate is human, to recurse, divine.
遞迴只應天上有, 凡人該當用迴圈.                  L. Peter Deutsch


--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 118.160.106.42
推 vip82:推!!                                                      05/01 05:12
推 sjgau:fortran have common block, it is global valriable         05/01 07:51

另一個Fortran的優勢是有前人寫的LAPACK等數值運算函式庫
以上為Fortran77

但Fortran90出現POINTER,Fortran2003全面支援OOP
是否使Fortran的速度不再快於C?

又有人說Fortran2008不再支援OOP,是真的嗎?

 作者  DrStein (交換關聯)                                     看板  C_and_CPP
 標題  [閒聊] 怒吼,PTT怎沒有fortran版
 時間  Sun Sep  7 17:06:15 2008
───────────────────────────────────────
...略
※ 發信站: 批踢踢實業坊(ptt.cc)
...略
→ DrStein:Fortran優勢有三: 1.有lapack等數值函式庫                 09/07 20:28
→ DrStein:2.前人的科學計算程式,大多是用fortran來寫               09/07 20:28
→ DrStein:3.好學 比起C/C++那種指標強制學習制(開檔必要用指標)      09/07 20:29
→ DrStein:fortran無疑是非專業程設者的第一選則                     09/07 20:30
→ DrStein:(4.) fortran 2008直接支援平行,那更是目前的趨勢         09/07 20:31
→ DrStein:fortran2003胎死負中的原因 就是因為全面支援OOP           09/07 20:31
→ DrStein:後來會議結論是OOP不該存在於fortran中                    09/07 20:32
→ DrStein:也就是fortran完全定位為科學計算程式                     09/07 20:32

http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&lang=gcc&lang2=ifc
上面的測試結果是用Fortran2003? 還是其他的版本?
是否有測試Fortran的強項?
Fortran的強項是什麼?(陣列? 迴圈?)

http://gcc.gnu.org/ml/fortran/2007-01/msg00619.html
g77的前身是g2c,也就是說用g77編譯Fortran時,她會先把Fortran翻成C
於是若拿g77當compiler,Fortran在速度上對C毫無優勢
那麼gfortran的編譯方式也是透過g2c嗎?

目前合法免費的Fortran compiler就只有gfortran?
須要用付費的Fortran compiler才能享有Fortran的高速嗎?

以下來個問題總結:
與C比較,Fortran的強項是什麼?(陣列? 迴圈? 複數? 禁止重複?)
該強項是比C快的原因是什麼?
哪些版本的Fortran快於C?
須要用付費的Fortran compiler才能完全享有Fortran的高速或強項嗎?

2011年10月3日 星期一

Constant Pointer


[18.5] What's the difference between "Fred const* p", "Fred* const p" and "Fred const* const p"?

http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5

You have to read pointer declarations right-to-left.

  • Fred const* p means "p points to a constant Fred": the Fred object can't be changed via p.
  • Fred* const p means "p is a const pointer to a Fred": you can't change the pointer p, but you can change the Fred object via p.
  • Fred const* const p means "p is a constant pointer to a constant Fred": you can't change the pointer p itself, nor can you change the Fred object via p.

const X& x and X const& x are equivalent.
const X* x and X const* x are equivalent.

TypeX const ... 可寫成 const TypeX ....

2011年10月2日 星期日

c++ class template cannot find its constructor

c++ class with template cannot find its constructor
http://stackoverflow.com/questions/644397/c-class-with-template-cannot-find-its-constructor

[35.12] Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?
http://www.parashift.com/c%2B%2B-faq-lite/templates.html#faq-35.12


A template is not a class or a function. A template is a "pattern" that the compiler uses to generate a family of classes or functions.

In order for the compiler to generate the code, it must see both the template definition (not just declaration) and the specific types/whatever used to "fill in" the template. For example, if you're trying to use a Foo<int>, the compiler must see both the Foo template and the fact that you're trying to make a specific Foo<int>.

Your compiler probably doesn't remember the details of one .cpp file while it is compiling another .cpp file. It could, but most do not and if you are reading this FAQ, it almost definitely does not. BTW this is called the "separate compilation model."

class template不是class,只是個pattern。compiler看到class template並不會製造出class,除非有使用到,才會在編譯過程中嘗試造出。

製造時,她必須要有class template的宣告與定義(實作),才能造出class method。
但compiler不會去記他之前看過的檔案,所以在有使用到template class的檔案裡,不只要include宣告,還要include定義(實做)。

/*A.hpp*/
template<class T>
class A
{...}

/*A.cpp*/
#include"A.hpp"
...

/*Main.cpp*/
#include"A.cpp"

另一種解法:(如果是用A<bool>)

/*A.hpp*/
template<class T>
class A
{...}

/*A.cpp*/
#include"A.hpp"
...
template class A<bool>; //令compiler現在就把A<bool>造出來

/*Main.cpp*/
#include"A.hpp"
//you can use A<bool>

如果你不能修改A.cpp的話,可以這樣:
/*A-impl.cpp*/
#include"A.cpp"
template class A<bool>;

2011年9月30日 星期五

IQ Light (Danish Design Award 2001)


如意燈是啥?
利用以圖找圖的搜尋引擎才找到他原來的名字iq light


官網
http://www.iqlight.com/
幾何原理介紹與組裝方法...等


如何組裝
http://www.iqlight.com/iqhowto2.htm
http://www.iqlight.com/iqhowto3.htm

如何放燈泡進去
http://www.iqlight.com/iqhowto4.htm


零件:



各種組法:

官網說明書
http://www.minuevohogar.cl/momentaneo/iq_light_1.jpg
http://www.minuevohogar.cl/momentaneo/iq_light_2.jpg
http://1.bp.blogspot.com/-F4v11qrYtl0/TVvWf9G2OEI/AAAAAAAAApE/_x9FC-i-yHE/s1600/13.jpg
心型
http://www.pyro-shop24.de/WebRoot/Store/Shops/61016434/4C1B/66D4/A231/13AA/1379/C0A8/28BE/C176/275_6_Jigsaw_Lamp_Shade___Puzzle_Lamp_11___Red_Heart_ms.jpg
圓柱形
http://f10.wretch.yimg.com/mimomimo/6/1402650704.jpg?5AyM2GNDcBawCjARloZrAr.11UWbIaUYyXHJig9vbV8wdOMW9m1aIRcs2Vw.3Iiskw--
星型
http://www.craftycrafty.tv/assets_c/2009/03/iqlightreplica-thumb-200x209-82697.jpg

各式組件:

用橢圓形組
http://www.flickr.com/photos/31375127@N07/3757533122/in/set-72157621834564772/
http://www.flickr.com/photos/yoshinobu_miyamoto/3757534282/in/set-72157621834564772

用撲克牌組
http://www.decoesfera.com/iluminacion/curiosas-lamparas-hechas-con-naipes

有稜角
http://www.flickr.com/photos/31375127@N07/3852173948/in/photostream
http://www.flickr.com/photos/yoshinobu_miyamoto/3851442667/in/photostream

勾住的地方變肥
http://www.flickr.com/photos/yoshinobu_miyamoto/3852174202/in/photostream/

長條

平面透視不是萬能

错误的透视原理
http://tech.ddvip.com/2008-12/122838426597480.html

我原以為只是胡說
但仔細看看其實有些道理

就幾何學來看,平面透視是正確的
但以人眼來看,平面透視確實有他奇怪的地方
當角度越大(超廣角),平面透視所呈現的畫面會越奇怪

混疊

混疊
http://zh.wikipedia.org/wiki/%E6%B7%B7%E7%96%8A
奈奎斯特頻率
http://zh.wikipedia.org/wiki/%E5%A5%88%E5%A5%8E%E6%96%AF%E7%89%B9%E9%A2%91%E7%8E%87
取樣定理
http://zh.wikipedia.org/wiki/%E9%87%87%E6%A0%B7%E5%AE%9A%E7%90%86
電子濾波器
http://zh.wikipedia.org/wiki/%E6%BB%A4%E6%B3%A2

數位紅外線攝影簡介

數位紅外線攝影簡介
http://article.dcview.com/newreadarticle.php?type=7&id=975

http://www.dcview.com.tw/photoclass/infrared/page_01.htm

http://tw.myblog.yahoo.com/owenniu-owenniu/article?mid=479

紅外線 攝影創作主題:夢想殿堂 中正大學

紅外線 攝影創作主題:夢想殿堂 中正大學
http://t17.techbang.com.tw/topics/996-infrared-photography-theme-the-dream-palace-of-national-chung-cheng-university

CSIE Communications

CSIE Communications
http://csiecomm.blogspot.com/

2011年9月28日 星期三

Fortran Filename extension

http://www.ats.ucla.edu/clusters/common/computing/compilers.htm

Fortran 90/Fortran 77 Commands associated with Compilers

CompilerSerial
* fileName extension, not command used, determines language version (can be changed by command flags)
Parallel
* See the MPI doc.
CommandsFortran 90 fileName extensionsFixed Format fileName extensionsFortran 90Fortran 77
Intelifort.f90 (.F90 preprocessed).f, .for, .ftn (.F, .FOR, .FTN, .FPP preprocessed)mpif90mpf77
GNUgfortran.f90 (.F90 preprocessed).f, .for, .ftn


http://software.intel.com/sites/products/documentation/hpc/compilerpro/en-us/fortran/lin/compiler_f/bldaps_for/common/bldaps_under_inpext.htm
Filename
Interpretation
Action


filename.f
filename.for
filename.ftn
filename.i
Fortran fixed-form source
Compiled by the Intel® Fortran compiler.
filename.fpp
and, on Linux, filenames with the following uppercase extensions: .FPP.F,.FOR.FTN
Fortran fixed-form source
Automatically preprocessed by the Intel Fortran preprocessor fpp; then compiled by the Intel Fortran compiler.
filename.f90
filename.i90
Fortran free-form source
Compiled by the Intel Fortran compiler.
filename.F90 (Linux OS and Mac OS X)
Fortran free-form source
Automatically preprocessed by the Intel Fortran preprocessor fpp; then compiled by the Intel Fortran compiler.


Filename ExtensionsSource Form/Preprocessing
.f, .fix, .for, .fpp, .ftn
.F, .F77, .FIX, .FOR, .FTN, .FPP, .fpp
Fixed source form
.f08, .f03, .f95, .f90Free source form with INCLUDE lines
.F08, .F03, .F95, .F90Free source form with C preprocessor directives

2011年9月19日 星期一

Re: [問題] 記憶體使用2的倍數效能低落

作者: littleshan (我要加入劍道社!) 看板: C_and_CPP
標題: Re: [問題] 記憶體使用2的倍數效能低落
時間: Thu Aug 25 12:20:54 2011

※ 引述《xxxx9659 (嘎嘎嘎嘎嘎)》之銘言:
: 當我每次位移 2 的次方倍數來存取記憶體時 效能會慢兩倍以上
: 在不同的電腦 不同的 OS 做測試 好像都有這現象
: 難道 2 的倍數很容易 cache miss ?
: 看程式碼比較好解釋 http://codepad.org/W81Vso04
: 我用直覺猜 2 的倍數應該比其他還快 解果剛好相反 整個改觀
: 這樣讓我不知道什麼地方用該用 2 的倍數 什麼地方不要用
: 有人對這種奇特現象有研究嗎@@
以下是我在一台 core-i3 的機器上
使用 gcc 4.6 x64 測試的結果:(有開 -O2)

        func(2000, 2047); 執行時間: 0.030 sec
        func(2000, 2048); 執行時間: 0.040 sec
        func(2000, 2049); 執行時間: 0.030 sec
        func(2000, 2050); 執行時間: 0.040 sec
        --
        func(2047, 2000); 執行時間: 0.030 sec
        func(2048, 2000); 執行時間: 0.060 sec
        func(2049, 2000); 執行時間: 0.030 sec
        func(2050, 2000); 執行時間: 0.040 sec

的確當 m=2048 的時候,花了比較久的時間,而且多次測試的結果均如此。

        *       *       *

要解釋這個現象,我目前想到的確是和 cache miss 有關。
cache 運作方式是這樣的 (以下是簡化許多的版本,實際運作更為複雜):

 1. 當 CPU 要取用記憶體時 (假設是某個位址 0xABCDFF00),首先它去 cache 中尋找,
    不過一開始當然 cache 中什麼都沒有,因此會直接從記憶體中讀取。

 2. 讀取到真正的資料後,為了加速之後對同一位址的存取速度,
    我們會把 0xABCDFF00 中的資料,存到 cache 中,但是要存在哪個位置呢?
    我們可不能隨便找一塊空的地方就塞進去,因為尋找 cache 中的資料也需要時間。
    所以比較好的做法是根據記憶體的位址,也就是 0xABDFF00,
    對應到 cache 中的特定位置,之後要尋找的時候就可以很快地找到資料。

 3. 最常見的做法,就是從位址中取出較低的某幾位,以我們的例子來說就是 0xFF00
    來當作我們存在 cache 中的位置。至於要取幾位,就視我們的 cache 有多大。
    以 64KB 的 cache 來說,取位址的低 16bit 剛剛好可以對應 cache 的大小。

 4. 但這會有一個問題,那就是若有兩塊記憶體,位址剛好間隔了 64K,那麼他們的
    低 16bit 會剛好相等,也就是對應到同一塊 cache 的空間。如果我們的程式同
    時存取這兩塊記憶體,因為這兩塊記憶體會互相爭奪它們在 cache 中的地位,
    將造成嚴重的 cache miss 而導致效能低落。

 5. 因此我們使用了一種折衷的方法。當我們取出位址的低 16bit,也就是 0xFF00 時,
    它對應到 cache 中的位置,並不是只有一塊空間,而是很多塊空間。當我們要在
    cache 中儲存資料時,可以在這些空間中選擇一塊使用。這麼一來,就得以解決上述
    「兩塊不同位址的記憶體對應到同一個 cache 位置」的問題,只要讓它們對應到
    同一個 cache 位置的不同空間即可。


若一個記憶體位址可以對應到 cache 中的 N 塊空間,
我們就稱這個 cache 是 N-way set associative cache。
典型的 2-way set associative cache 的結構是長這樣的:

       index        way 0             way 1
   ┌────┬──┬────┬┬──┬────┐
   │    0   │ tag│  data  ││ tag│  data  │
   ├────┼──┼────┼┼──┼────┤
   │    1   │ tag│  data  ││ tag│  data  │
   ├────┼──┼────┼┼──┼────┤
        ...     ...    ...        ...    ...

其中的 index 就是由記憶體位址所算出來的 cache 編號,
一個編號可以對應到兩塊空間,也就是 way 0 和 way 1。
而 cache 中除了會存記憶體中的資料(data)以外,還會儲存「tag」,
也就是標記這塊資料原本的記憶體位址,
我們才能知道那塊資料是否確定就是我們要的。

回到你的問題。在你的 code 中,最內層的迴圈是這麼寫的:

    for(j=0; j<n; ++j){
      mA[j*m+i] = mB[i*n+j]; //mA[第j列, 第i行] = mB[第i列, 第j行]
    }

當 m 等於 2048 的時候, mA[j*m+i] 這行每次寫入的位址
都和上一次寫入時間隔了 8K byte (假設這時int的大小為4byte)
又假設 CPU 的 L1 cache 大小為 64K
這表示 j=0,  8, 16, ... 的時候,會寫入到同一塊 cache set中,
同樣地 j=1,  9, 17, ...
以及   j=2, 10, 18, ... 這些情況都會各自寫進同一塊 cache set 中。

通常 L1 data cache 為了提高速度,associativity 不會太高 (2-way 到 8-way 之間)
因此上述的情況將導致嚴重的 write miss,
CPU 需要花時間等待 cache 中的資料寫回記憶體中,
才能繼續寫入資料。

結論:算盤本是個好物

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.32.15.163
推 james732:唸那本書的時候這個章節真的很頭昏...XD                  08/25 12:21
推 xxxx9659:喔喔喔 原本cache的概念很模糊 看完這篇清晰許多!!!    08/25 12:45
→ xxxx9659:所以存取時 位移不要用2的次方 但是malloc可以用2的次方   08/25 12:49
→ littleshan:malloc要看實作的方式                                 08/25 13:07