[問題] 如何在編譯期建表

看板C_and_CPP作者 (noOneKnows)時間12年前 (2013/10/23 22:26), 編輯推噓7(7041)
留言48則, 7人參與, 最新討論串1/3 (看更多)
小弟需要在編譯期建一張很大的表,需求大概像這樣子, 簡化起見,假設長度 N,式子為 Exponential value of (index * alpha) 我希望達到這樣的效果: static const double alpha = 3.0; static const double Table[N] = { exp(0*alpha), exp(1*alpha), exp(2*alpha), ... exp(i*alpha), ... exp((N-1)*alpha) }; 我希望一開始就把這個結果 load 到記憶體,就像手動宣告以上程式碼這樣。 而不可以做成 static Table[N]; Table[0] = exp(0*alpha); Table[1] = exp(1*alpha); ... Table[N-1] = exp((N-1)*alpha); 目前沒想到什麼好方法,主要是宣告 array 這塊,還要保證記憶體連續,還有實際上的 式子遠比 exp 複雜也希望不要使用數學展開成遞迴。 請問有人有好方法嗎? 感謝! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 123.241.67.33

10/23 22:28, , 1F
看到這個就讓我想到 Template metaprogramming
10/23 22:28, 1F

10/23 22:28, , 2F
沒太仔細研究不太清楚是否可行,你研究看看
10/23 22:28, 2F

10/23 22:28, , 3F
不然你就先算好,然後讀檔進來
10/23 22:28, 3F

10/23 22:29, , 4F
寫一個程式輸出成宣告的語法, 放在 .h 裡面 include 即可
10/23 22:29, 4F

10/23 22:29, , 5F
嗯啊我只想到先算好然後複製貼上
10/23 22:29, 5F

10/23 22:29, , 6F
目前想到跟四樓一樣的做法,但工作忙的時候要多一道工
10/23 22:29, 6F

10/23 22:30, , 7F
我自己比較喜歡直接輸出成 .o 再 link, 因為我的表都超級
10/23 22:30, 7F

10/23 22:30, , 8F
希望能有只要改 alpha 就好
10/23 22:30, 8F

10/23 22:30, , 9F
大, 輸出成 C 語言 compile 時會很慢...
10/23 22:30, 9F

10/23 22:30, , 10F
最差情況就是寫成批次命令了
10/23 22:30, 10F

10/23 22:32, , 11F
可是輸出成 .o 改參數的時候還是要重新製作 .o 檔吧
10/23 22:32, 11F

10/23 22:33, , 12F
你可以用Makefile做啊,Visual系列就寫建置前事件(批次)
10/23 22:33, 12F

10/23 22:35, , 13F
VC++的建置前事件比較短路,make可以自動判斷某個檔有無更
10/23 22:35, 13F

10/23 22:35, , 14F
嗯嗯啊,我也是想到這種作法,但想有沒有可能用template
10/23 22:35, 14F

10/23 22:36, , 15F
新再決定這個 .o 或 .table 檔需不需要再重新計算一遍
10/23 22:36, 15F

10/23 22:36, , 16F
因為如果我要用 makefile 我就得幫同事 set up XD
10/23 22:36, 16F

10/23 22:37, , 17F
所以 template 是無解的嗎?感覺好像真的只能用批次做..
10/23 22:37, 17F

10/23 22:51, , 18F
http://ideone.com/jXSpbg 有點undefined behavior...
10/23 22:51, 18F

10/23 23:01, , 19F
感謝!!!可是這樣沒辦法把計算移到編譯期
10/23 23:01, 19F

10/23 23:05, , 20F
那只能自己寫個constexpr版的exp
10/23 23:05, 20F

10/23 23:06, , 21F
其他的應該會被最佳化
10/23 23:06, 21F

10/23 23:07, , 22F
其他的部分是指?
10/23 23:07, 22F

10/23 23:13, , 23F
剛看來 constexpr 應該是符合我的需求,真的很感謝
10/23 23:13, 23F

10/23 23:14, , 24F
實在大感謝了
10/23 23:14, 24F

10/23 23:35, , 25F
忽然想到,這樣有記憶體連續嗎
10/23 23:35, 25F

10/23 23:37, , 26F
"一般而言"有
10/23 23:37, 26F

10/24 00:13, , 27F
似乎是~~總之感謝
10/24 00:13, 27F

10/24 00:33, , 28F

10/24 01:52, , 29F
我寧可用程式去寫程式,除了可以建表,還可以作神奇的事
10/24 01:52, 29F

10/24 01:53, , 30F
例如把local變數->global,迴圈拆成goto 加速等等 XD
10/24 01:53, 30F

10/24 01:55, , 31F
或者是把很多 *.c *.h 貼成一整份code 加速 XD
10/24 01:55, 31F

10/24 01:59, , 32F
這個與其說是加速,感覺比較像在產生unmaintainable code
10/24 01:59, 32F

10/24 02:13, , 33F
maintainable code -> optimizer -> dirty code -> ...
10/24 02:13, 33F

10/24 02:13, , 34F
不做這些事當然也可以
10/24 02:13, 34F

10/24 02:14, , 35F
就直接編一編連一連就好了
10/24 02:14, 35F

10/24 02:20, , 36F
我只是想把前面幾篇的梗連起來...
10/24 02:20, 36F

10/24 07:48, , 37F
為什麼貼成一整份 code 速度比較快
10/24 07:48, 37F

10/24 09:19, , 38F
p大的做法效果有限 有時還會影響優化演算法的判斷
10/24 09:19, 38F

10/24 11:39, , 39F
請參考SQLite
10/24 11:39, 39F

10/24 13:55, , 40F
那你要不要試試把llvm全部都合在一起?
10/24 13:55, 40F

10/24 14:00, , 41F
現在是因為LTO還很弱 才讓你可以這樣做
10/24 14:00, 41F

10/24 14:00, , 42F
而且llvm linker的優化本身就是把所有.o檔merge起來 丟回
10/24 14:00, 42F

10/24 14:01, , 43F
llvm做優化 另外loop拆成goto 那那些parallel的優化算法
10/24 14:01, 43F

10/24 14:02, , 44F
就不能做惹 optimize過的扣的又不是給你看的 你為了你自以
10/24 14:02, 44F

10/24 14:03, , 45F
為的假優化 才是真正的dirty code
10/24 14:03, 45F

10/24 14:09, , 46F
每個 project 都有其目的,這邊只是提出一個可能的選項
10/24 14:09, 46F

10/24 14:11, , 47F
最終要做出怎樣的東西,端看目的為何,沒有一招可以吃全部
10/24 14:11, 47F

10/24 14:13, , 48F
總之就是取捨,有好有壞自行評估,跑數據證明有效就行了
10/24 14:13, 48F
文章代碼(AID): #1IPznxf5 (C_and_CPP)
文章代碼(AID): #1IPznxf5 (C_and_CPP)