查看完整版本 : 原來 Julia 是很慢的!

xianrenb 2017-11-16 07:55 PM

原來 Julia 是很慢的!

[url=https://en.wikipedia.org/wiki/Julia_(programming_language)]https://en.wikipedia.org/wiki/Julia_(programming_language)[/url]
[quote]...Good performance, approaching that of statically-typed languages like C...[/quote]
說得很好,但今天終於認清事實, Julia 其實是很慢的![code]julia> macro loop(n, ex)
         return quote
           for i=1:$n
             $ex
           end
         end
       end
@loop (macro with 1 method)

julia> function f(a::Array{Int64,1})
         sum = 0
         for v = a
           sum += v
         end
         sum
       end
f (generic function with 1 method)

julia> a1 = collect(1:100); a2 = collect(1:10); a3 = collect(1:2)
2-element Array{Int64,1}:
1
2

julia> @time @loop(2, f(a1))
  0.010744 seconds (52 allocations: 3.063 KB)

julia> @time @loop(2, f(a1))
  0.000008 seconds (2 allocations: 32 bytes)

julia> @time @loop(1002, f(a1))
  0.000242 seconds (1.00 k allocations: 15.656 KB)

julia> @time @loop(1002, f(a1))
  0.000240 seconds (1.00 k allocations: 15.656 KB)

julia> @time @loop(2, f(a2))
  0.000007 seconds

julia> @time @loop(2, f(a2))
  0.000008 seconds

julia> @time @loop(1002, f(a2))
  0.000092 seconds

julia> @time @loop(1002, f(a2))
  0.000091 seconds

julia> @time @loop(2, f(a3))
  0.000009 seconds

julia> @time @loop(2, f(a3))
  0.000003 seconds

julia> @time @loop(1002, f(a3))
  0.000077 seconds

julia> @time @loop(1002, f(a3))
  0.000077 seconds[/code]以 10 個 element 的 a2 為例, 1002 - 2 = 1000 次的 f(a2) 要 91 - 8 = 83 us 。
即 1 次 f(a2) 要 83 ns 。
iterate 每個 element 時間就約是 8.3 ns 。
我用的 Processor 只是 2.16 GHz 的 N2840 。
所以 clock cycle 約是 0.463 ns 。
8.3 / 0.463 ~= 18 倍!
同原先想像中的 2~3 倍差很遠。

p.s.
上面說的時間,是等效時間。
當然從 f(a3) 的表現,得知 for loop 及 function call 的 overhead 很大。

[[i] 本帖最後由 xianrenb 於 2017-11-16 07:57 PM 編輯 [/i]]

Susan﹏汪汪 2017-11-16 08:03 PM

汪汪一向覺得行VM的語言好難快得到

sswroom 2017-11-16 08:48 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-11-16 08:03 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=470991664&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
汪汪一向覺得行VM的語言好難快得到 [/quote]其實怎樣才算是VM語言呢?
x86 Machine Code要Realtime Compile成Micro-op code才Execute的算不算是VM語言呢?

Susan﹏汪汪 2017-11-16 09:02 PM

[quote]原帖由 [i]sswroom[/i] 於 2017-11-16 08:48 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=470993672&ptid=27063084][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]
其實怎樣才算是VM語言呢?
x86 Machine Code要Realtime Compile成Micro-op code才Execute的算不算是VM語言呢? [/quote]
大概係

相對於運行環境中、最底層能夠直接執行的指令碼
例如machine code
需要係上面建立虛擬機先行得到的語言

如果你用virtual box行Windows
裡面再行C++

個C++相對於virtual box裡面的windows 都不算係VM語言

sswroom 2017-11-16 09:18 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-11-16 09:02 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=470994244&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

大概係

相對於運行環境中、最底層能夠直接執行的指令碼
例如machine code
需要係上面建立虛擬機先行得到的語言

如果你用virtual box行Windows
裡面再行C++

個C++相對於virtual box裡面的windows 都不算係VM語言 [/quote]但是Machine Code會被CPU Compile成Micro-op Code才Execute, x86 CPU真正Execute的是Micro-op code, 不是Machine Code
CPU有時有Bug, 會修改Compiler(Update Firmware)去修正問題.......

Susan﹏汪汪 2017-11-16 09:34 PM

[quote]原帖由 [i]sswroom[/i] 於 2017-11-16 09:18 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=470994928&ptid=27063084][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]
但是Machine Code會被CPU Compile成Micro-op Code才Execute, x86 CPU真正Execute的是Micro-op code, 不是Machine Code
CPU有時有Bug, 會修改Compiler(Update Firmware)去修正問題....... [/quote]
所以就係話「相對」

如果你把運行環境定為Java machine
咁Java就係native

有人發明個新語言
用Java bytecode 砌VM再係上面行
對於Java machine 黎講呢個新語言就係VM語言

ncream 2017-11-16 09:52 PM

[quote]原帖由 [i]sswroom[/i] 於 2017-11-16 09:18 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=470994928&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
但是Machine Code會被CPU Compile成Micro-op Code才Execute, x86 CPU真正Execute的是Micro-op code, 不是Machine Code
CPU有時有Bug, 會修改Compiler(Update Firmware)去修正問題....... [/quote]

Ching我想知落果想再加快速度。可唔可以直接寫micro-op code。跳過machine code

ncream 2017-11-16 09:54 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-11-16 09:34 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=470995645&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

所以就係話「相對」

如果你把運行環境定為Java machine
咁Java就係native

有人發明個新語言
用Java bytecode 砌VM再係上面行
對於Java machine 黎講呢個新語言就係VM語言 [/quote]

Java出左無幾耐。就有傳sun會出執行bytecode處理器。最後無聲無氣。若果有java就係native。

sswroom 2017-11-16 10:02 PM

[quote]原帖由 [i]ncream[/i] 於 2017-11-16 09:52 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=470996502&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


Ching我想知落果想再加快速度。可唔可以直接寫micro-op code。跳過machine code [/quote]不同CPU的Micro-op code未必一樣, 但x86 Machine Code很接近, 所以直接寫Assembly會最快, 因為Assembly與Machine Code是1:1, 速度上沒有分別。

form5 2017-11-16 11:32 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-16 07:55 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=470991325&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
[url=https://en.wikipedia.org/wiki/Julia_]https://en.wikipedia.org/wiki/Julia_[/url](programming_language)

說得很好,但今天終於認清事實, Julia 其實是很慢的!julia> macro loop(n, ex)
         return quote
           for i=1:$n
             $e ... [/quote]
測試用ns 做單位是不會凖确的
之前睇benchmark 比較 , Julia 吾算慢, 夠用瓜

xianrenb 2017-11-17 08:40 AM

[quote]原帖由 [i]form5[/i] 於 2017-11-16 11:32 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471001474&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

測試用ns 做單位是不會凖确的
之前睇benchmark 比較 , Julia 吾算慢, 夠用瓜 [/quote]

看來 Julia @time 的準確度去到 0.000001 秒,即是 1 us 。
而從數次 @time 的結果看來,數值基本上是穩定的,只是第一次 run macro 要 JIT ,所以比較耐。
前面的計算,只是算出等效的時間。

其實我想說的是 Julia 在 array size 比較細,亦可能是某些應用的情況時,其效能不佳。
一般 benchmark ,很可能用大 size 的 array 。
如 a1 是 100 個 element 的。
1002 - 2 = 1000 次的 f(a1) 約花 240 - 8 = 232 us 。
1 次 f(a1) 的時間會是 232 ns 。
iterate 1 個 element 的等效時間,會是 2.32 ns 。
這個時間,看起來就好得多。

所以如果 benchmark 用大數值的 array size ,就見不到個問題。
現實中寫程式, array size 通常不大。
某些應用更可能常用小數值的 array size 。
另外,從上面測試亦可以估計, Julia 在其他方面的效能,如 function call 亦很慢。

以前我以為 Julia 很快。
現在已經完全改觀。

看來要效能高,唯一選擇都是用 static typing 的語言。

Susan﹏汪汪 2017-11-17 08:44 AM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-17 08:40 AM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=471010926&ptid=27063084][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


看來 Julia @time 的準確度去到 0.000001 秒,即是 1 us 。
而從數次 @time 的結果看來,數值基本上是穩定的,只是第一次 run macro 要 JIT ,所以比較耐。
前面的計算,只是算出等效的時間。

其實我想說的 ... [/quote]
汪汪而家自己做benchmark都有個習慣

一開波都會先print(Date().timeIntervalSinceNow)

可以force pre-load Foundation Library

因為汪汪發現無論點做都好
不理你個程式第一件事係做乜
第一次的timing 一定係唔準

[[i] 本帖最後由 Susan﹏汪汪 於 2017-11-17 08:46 AM 編輯 [/i]]

Susan﹏汪汪 2017-11-17 08:52 AM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-17 08:40 AM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=471010926&ptid=27063084][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


看來 Julia @time 的準確度去到 0.000001 秒,即是 1 us 。
而從數次 @time 的結果看來,數值基本上是穩定的,只是第一次 run macro 要 JIT ,所以比較耐。
前面的計算,只是算出等效的時間。

其實我想說的 ... [/quote]
你知唔知Julia 的function call係static 定symbol

sswroom 2017-11-17 08:57 AM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-11-17 08:44 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471011094&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

汪汪而家自己做benchmark都有個習慣

一開波都會先print(Date().timeIntervalSinceNow)

可以force pre-load Foundation Library

因為汪汪發現無論點做都好
不理你個程式第一件事係做乜
第一次的timing 一定係唔準 [/quote]但是我用Linux和Windows都沒有這個情況, 可能是你用的API問題........ Linux是用gettimeofday()來計時, Windows是用QueryPerformanceCounter()

Susan﹏汪汪 2017-11-17 09:14 AM

[quote]原帖由 [i]sswroom[/i] 於 2017-11-17 08:57 AM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=471011697&ptid=27063084][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]
但是我用Linux和Windows都沒有這個情況, 可能是你用的API問題........ Linux是用gettimeofday()來計時, Windows是用QueryPerformanceCounter() [/quote]
因為而家的系統都係lazy loading

你用來做timing 的工具如果係同程式一開始就必要的功能係放埋一齊
咁你的timing都會一齊預先load好

汪汪用的Date係蘋果的Foundation framework
不是standard module

Susan﹏汪汪 2017-11-17 10:26 AM

有趣

macOS有好幾個library 種類
有framework 、dylib等等

印象中macOS不同的lib係有些會lazy loading
有些係一次過全部load晒

Framework 係lazy loading的(大概)
但如果用C++寫dylib又如何

首先寫左呢個
global_variable同main同一個project 裡面
而且就算main冇用過global_variable都會做init
所以一樣會print左一句野出來
[code]

#include <iostream>

int lazy_test() {
    std::cout << "lazy_test\n";
    return 0;
}

int global_variable = lazy_test();

int main(int argc, const char * argv[]) {
   
    return 0;
}

[/code]

汪汪試左把global_variable搬左去dylib
再link返入program

結果一樣不需要main使用個global_variable都會自己init左

form5 2017-11-17 09:23 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-17 08:40 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471010926&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

看來 Julia @time 的準確度去到 0.000001 秒,即是 1 us 。
而從數次 @time 的結果看來,數值基本上是穩定的,只是第一次 run macro 要 JIT ,所以比較耐。
前面的計算,只是算出等效的時間。

其實我想說的 ... [/quote]
睇少左三個零
不過,我記得Windows 上個 timer resolution 可以 有4 至 15 ms 誤差

[[i] 本帖最後由 form5 於 2017-11-17 10:50 PM 編輯 [/i]]

fitcat07 2017-11-17 10:50 PM

[quote]原帖由 [i]form5[/i] 於 2017-11-17 09:23 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471048167&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

睇少左三個零
不過,我記得Windows 上個鐘 有4 至 15 ms 誤差 [/quote]
如無記錯,Windows有high resolution timer,好似去到micro seconds。

form5 2017-11-17 11:04 PM

[quote]原帖由 [i]fitcat07[/i] 於 2017-11-17 10:50 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471051967&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

如無記錯,Windows有high resolution timer,好似去到micro seconds。 [/quote]
好似係,julia 吾知係吾係用 high resolution timer
之前做measuring 用query performance counter

sswroom 2017-11-17 11:33 PM

[quote]原帖由 [i]fitcat07[/i] 於 2017-11-17 10:50 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471051967&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

如無記錯,Windows有high resolution timer,好似去到micro seconds。 [/quote]Windows用QueryPerformanceCounter()理論上準確度去到CPU的Frequency, 但實際上誤差約為 0.3 micro second.
而Linux/mac用gettimeofday()的誤差是1 micro second

Susan﹏汪汪 2017-11-17 11:42 PM

[quote]原帖由 [i]sswroom[/i] 於 2017-11-17 11:33 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=471054099&ptid=27063084][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]
Windows用QueryPerformanceCounter()理論上準確度去到CPU的Frequency, 但實際上誤差約為 0.3 micro second.
而Linux/mac用gettimeofday()的誤差是1 micro second [/quote]
http://en.cppreference.com/w/c/chrono/timespec_get

Susan﹏汪汪 2017-11-17 11:45 PM

而家C11方便好多

好多POSIX API都納入左C11

xianrenb 2017-11-18 08:42 AM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-11-17 08:52 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471011439&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

你知唔知Julia 的function call係static 定symbol [/quote]

static function call vs symbolic function call ?
我理解唔到。

不過 Julia 內有 symbol 。
如[code]:symbol1[/code]我估我個 macro 無寫錯掛。
應該都是 loop 個 ex(pression) ,即是 f(a1) 、 f(a2) 等等。

xianrenb 2017-11-18 08:54 AM

再 benchmark 多一次,呢次直接 loop 1e6 次。[code]julia> macro loop(n, ex)
         return quote
           for i=1:$n
             $ex
           end
         end
       end
@loop (macro with 1 method)

julia> function f(a::Array{Int64,1})
         sum = 0
         for v = a
           sum += v
         end
         sum
       end
f (generic function with 1 method)

julia> a1 = collect(1:100); a2 = collect(1:10); a3 = collect(1:2)
2-element Array{Int64,1}:
1
2

julia> @time @loop(1e6, f(a1))
  0.255625 seconds (1.00 M allocations: 15.262 MB)

julia> @time @loop(1e6, f(a1))
  0.385957 seconds (1000.00 k allocations: 15.259 MB, 38.37% gc time)

julia> @time @loop(1e6, f(a1))
  0.251396 seconds (1000.00 k allocations: 15.259 MB, 3.82% gc time)

julia> @time @loop(1e6, f(a2))
  0.089153 seconds

julia> @time @loop(1e6, f(a2))
  0.086719 seconds

julia> @time @loop(1e6, f(a2))
  0.088792 seconds

julia> @time @loop(1e6, f(a3))
  0.076976 seconds

julia> @time @loop(1e6, f(a3))
  0.071984 seconds

julia> @time @loop(1e6, f(a3))
  0.076924 seconds[/code]1 次 f(a2) 的時間約為 88.792 ms / 1e6 = 88.792 ns 。
iterate 每個 element ,約花 88.792 / 10 = 8.8792 ns 。
比 1 樓的數值還差一點。

Susan﹏汪汪 2017-11-18 09:03 AM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-18 08:42 AM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=471063906&ptid=27063084][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


static function call vs symbolic function call ?
我理解唔到。

不過 Julia 內有 symbol 。
如:symbol1我估我個 macro 無寫錯掛。
應該都是 loop 個 ex(pression) ,即是 f(a1) 、 f(a2) 等等。 [/quote]
即例如Objective-C咁

佢call methods 不是直接知道function pointer跳去implement

而係有個runtime 的表
查signature 去攞function pointer

Objective-C/Swift叫呢個signature 做selector

[[i] 本帖最後由 Susan﹏汪汪 於 2017-11-18 09:04 AM 編輯 [/i]]

xianrenb 2017-11-18 07:37 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-11-18 09:03 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471064527&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

即例如Objective-C咁

佢call methods 不是直接知道function pointer跳去implement

而係有個runtime 的表
查signature 去攞function pointer

Objective-C/Swift叫呢個signature 做selector [/quote]

呢個我都唔知。

不過 Julia 論語言本身是 dynamic typing 及 multiple dispatch 的。
理論上 run-time 才能確定同一個 function 名是 run 那一個 method 。
但實際上可能是 run 一次就 JIT 左做固定的 function/method call 。
對於 type-stable 的 variable/function input/output,大概一切都是固定的。

xianrenb 2017-11-18 07:50 PM

其實發現這個問題,是因為近日想為我的中國象棋程式加番個 GUI 介面。
一方面因為懶,二來想 standard d ,結果就考慮以 WinBoard 為結合目標。
也就試用了 WinBoard 中國象棋版內裏的 AI 引擎。
總之就知道,原來現代中國象棋 AI 引擎,可以隨時上 1 百萬 NPS (nodes per second) 。
我的象棋程式本來無相關統計功能,後來加了,才知道數值估計約 50 k NPS 左右!
但想來想去,也想不出論算法而言,為何這數值可以差那麼多。
因為算法不同可以層數與 nodes 比例不同,但 NPS 應該相若才對。
最後就懷疑根本是 Julia 不夠快。
終於寫 benchmark 引證了這一點。

[[i] 本帖最後由 xianrenb 於 2017-11-18 07:56 PM 編輯 [/i]]

煙民母親生賤種 2017-11-18 10:41 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-18 07:50 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471092371&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
其實發現這個問題,是因為近日想為我的中國象棋程式加番個 GUI 介面。
一方面因為懶,二來想 standard d ,結果就考慮以 WinBoard 為結合目標。
也就試用了 WinBoard 中國象棋版內裏的 AI 引擎。
總之就知道,原來 ... [/quote]咁你有無睇過 cpu 用量幾多? :fst_007:

xianrenb 2017-11-19 08:38 AM

[quote]原帖由 [i]煙民母親生賤種[/i] 於 2017-11-18 10:41 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471101016&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
咁你有無睇過 cpu 用量幾多? :fst_007: [/quote]

其實之前都唔知,原來 single thread 程式,如我的象棋程式,在一般 Windows (10) setting 情況下,還是應該會用了所有 logical CPU 的。
[url=https://superuser.com/questions/26240/why-is-a-single-thread-spread-across-cpus]https://superuser.com/questions/26240/why-is-a-single-thread-spread-across-cpus[/url]
set 了 process affinity(親和性)為 CPU 0 後, run 相關功能時見到用到盡 100% CPU 使用率。
有趣的是,正常地用兩個 logical CPU 理論上會有 cache miss ,但事實是反而會快些的。

煙民母親生賤種 2017-11-19 03:58 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-19 08:38 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471114897&ptid=27063084][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


其實之前都唔知,原來 single thread 程式,如我的象棋程式,在一般 Windows (10) setting 情況下,還是應該會用了所有 logical CPU 的。
[url=https://superuser.com/questions/26240/why-is-a-single-thread-sprea]https://superuser.com/questions/26240/why-is-a-single-thread-sprea[/url] ... [/quote]linux 都會 switch busy process 去不同 core 度。睇住佢由一個掉去另一個。不過咁只係 core switch , 唔代表 all cores 都用齊。:fst_005:
頁: [1] 2
查看完整版本: 原來 Julia 是很慢的!