Linuxマシンのメモリ帯域を測定したくなりました。いつもはddコマンドでやっているのですが、どの程度正確なのかいまいち分からないので。。。
メモリ帯域を測定するツールにStreamというものがあります。今回はこれを使います。このエントリにはその使い方と測定結果と考察を書きました。
デフォルトのstreamですと、昨今のコンピュータの性能を鑑みるに測定サイズが小さすぎるので一桁あげています。あげるために、コンパイル方法が少し異なります。具体的には、
gcc -O -mcmodel=large -DSTREAM_ARRAY_SIZE=100000000 stream.c -o stream.100M
と、「-mcmodel=large -DSTREAM_ARRAY_SIZE=100000000」を付加します。
以下、具体的な方法です↓。ちなみに、最適化オプションですが-Oで行いました。-O2ではありません。推奨が-Oだったので、それに準拠した感じです。
# ソースを落としてくる $ wget http://www.cs.virginia.edu/stream/FTP/Code/stream.c --2013-07-21 02:56:53-- http://www.cs.virginia.edu/stream/FTP/Code/stream.c Resolving www.cs.virginia.edu (www.cs.virginia.edu)... 128.143.137.29 Connecting to www.cs.virginia.edu (www.cs.virginia.edu)|128.143.137.29|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 19967 (19K) Saving to: `stream.c' 100%[===========================================================================================================================================>] 19,967 52.5K/s in 0.4s 2013-07-21 02:56:55 (52.5 KB/s) - `stream.c' saved [19967/19967] # コンパイルする $ gcc -O -mcmodel=large -DSTREAM_ARRAY_SIZE=100000000 stream.c -o stream.100M # 測定する $ ./stream.100M ------------------------------------------------------------- STREAM version $Revision: 5.10 $ ------------------------------------------------------------- This system uses 8 bytes per array element. ------------------------------------------------------------- Array size = 100000000 (elements), Offset = 0 (elements) Memory per array = 762.9 MiB (= 0.7 GiB). Total memory required = 2288.8 MiB (= 2.2 GiB). Each kernel will be executed 10 times. The *best* time for each kernel (excluding the first iteration) will be used to compute the reported bandwidth. ------------------------------------------------------------- Your clock granularity/precision appears to be 1 microseconds. Each test below will take on the order of 120877 microseconds. (= 120877 clock ticks) Increase the size of the arrays if this shows that you are not getting at least 20 clock ticks per test. ------------------------------------------------------------- WARNING -- The above is only a rough guideline. For best results, please be sure you know the precision of your system timer. ------------------------------------------------------------- Function Best Rate MB/s Avg time Min time Max time Copy: 9542.1 0.167732 0.167678 0.167769 Scale: 9818.7 0.162996 0.162954 0.163030 Add: 11098.8 0.216290 0.216239 0.216334 Triad: 11003.0 0.218197 0.218123 0.218254 ------------------------------------------------------------- Solution Validates: avg error less than 1.000000e-13 on all three arrays -------------------------------------------------------------
ちなみに↑と同じマシンでddコマンドで測定してみた例↓です。
$ dd if=/dev/zero of=/dev/null bs=100K count=100000 100000+0 records in 100000+0 records out 10240000000 bytes (10 GB) copied, 0.692448 s, 14.8 GB/s
評価:
Streamで10GB/s程度、ddコマンドで14.8GB/sということで、まあおおよそ一致、と言えるのでしょうかね?シングルプロセスによる測定なので、2コアのマシンなら実質この倍使えるということなのでしょう。
↑のマシンのスペックは、
– G540
– Intel(R) Celeron(R) CPU G540 @ 2.50GHz
– DDR3-1600 のDRAM 8GB * 2 (ただし、$ lshw で見てみると、1067MHz駆動のようです)
– Ubuntu 12.04.2 Server AMD64
– Linux Kernel 3.2.0-49-generic #75-Ubuntu SMP
– gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
です。
加えて、手持ちの富士通マシンでも測定してみました。
– Opteron 3280
– DDR3-1333 4GB * 2
– Ubuntu 12.04.2 Server AMD64
– Linux Kernel 3.5.0-36-generic #57~precise1-Ubuntu SMP
– gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
$ gcc -O -mcmodel=large -DSTREAM_ARRAY_SIZE=100000000 stream.c -o stream.100M $ ./stream.100M ------------------------------------------------------------- STREAM version $Revision: 5.10 $ ------------------------------------------------------------- This system uses 8 bytes per array element. ------------------------------------------------------------- Array size = 100000000 (elements), Offset = 0 (elements) Memory per array = 762.9 MiB (= 0.7 GiB). Total memory required = 2288.8 MiB (= 2.2 GiB). Each kernel will be executed 10 times. The *best* time for each kernel (excluding the first iteration) will be used to compute the reported bandwidth. ------------------------------------------------------------- Your clock granularity/precision appears to be 1 microseconds. Each test below will take on the order of 183660 microseconds. (= 183660 clock ticks) Increase the size of the arrays if this shows that you are not getting at least 20 clock ticks per test. ------------------------------------------------------------- WARNING -- The above is only a rough guideline. For best results, please be sure you know the precision of your system timer. ------------------------------------------------------------- Function Best Rate MB/s Avg time Min time Max time Copy: 6385.6 0.251072 0.250563 0.251651 Scale: 6222.1 0.257535 0.257150 0.257991 Add: 7221.6 0.332633 0.332334 0.332919 Triad: 7058.7 0.340359 0.340005 0.340577 ------------------------------------------------------------- Solution Validates: avg error less than 1.000000e-13 on all three arrays ------------------------------------------------------------- $ dd if=/dev/zero of=/dev/null bs=100K count=100000 100000+0 records in 100000+0 records out 10240000000 bytes (10 GB) copied, 1.42714 s, 7.2 GB/s
あまり7GB/s程度ですか。まあ8coresあるので、もっと行けるかもですが。
ちなみに結論としては、
$ dd if=/dev/zero of=/dev/null bs=100K count=100000はそこそこ精度が良さそうという感じです。Streamをコンパイルするのは面倒ですのでこれで十分感がありますね。