【问题标题】:Slowdown of pi calculation when Timer is used使用 Timer 时 pi 计算速度变慢
【发布时间】:2017-11-29 21:03:36
【问题描述】:

以下代码是我计算 pi = 3.1415 的代码...大约使用this 公式:

use Time;
var timer = new Timer();

config const n = 10**9;
var x = 0.0, s = 0.0;

// timer.start();                                     // [1]_____

for k in 0 .. n {
    s = ( if k % 2 == 0 then 1.0 else -1.0 );  // (-1)^k
    x += s / ( 2.0 * k + 1.0 );
}

// timer.stop();                                      // [2]_____
// writeln( "time = ", timer.elapsed() );             // [3]_____

   writef( "pi (approx) = %30.20dr\n", x * 4 );
// writef( "pi (exact)  = %30.20dr\n", pi );          // [4]_____

当上面的代码编译为chpl --fast test.chpl,执行为time ./a.out,那么它的运行时间为~4秒

pi (approx) =         3.14159265458805059268

real    0m4.334s
user    0m4.333s
sys     0m0.006s

另一方面,如果我取消注释 Lines [1--3] (以使用 Timer ),程序运行速度会慢得多 ~10 秒

time = 10.2284
pi (approx) =         3.14159265458805059268

real    0m10.238s
user    0m10.219s
sys     0m0.018s

当我只取消注释 Line [4](打印 pi 的内置值,Lines [1-3] 保持注释掉)时,同样会出现减速:

pi (approx) =         3.14159265458805059268
pi (exact)  =         3.14159265358979311600

real    0m10.144s
user    0m10.141s
sys     0m0.009s

所以我想知道为什么会出现这种减速...

我是否遗漏了上述代码中的某些内容(例如,Timer 的错误用法)?

我的环境是通过自制软件安装的 OSX10.11 + chapel-1.16。 更多详情如下:

$ printchplenv --anonymize
CHPL_TARGET_PLATFORM: darwin
CHPL_TARGET_COMPILER: clang
CHPL_TARGET_ARCH: native
CHPL_LOCALE_MODEL: flat
CHPL_COMM: none
CHPL_TASKS: qthreads
CHPL_LAUNCHER: none
CHPL_TIMERS: generic
CHPL_UNWIND: none
CHPL_MEM: jemalloc
CHPL_MAKE: make
CHPL_ATOMICS: intrinsics
CHPL_GMP: gmp
CHPL_HWLOC: hwloc
CHPL_REGEXP: re2
CHPL_WIDE_POINTERS: struct
CHPL_AUX_FILESYS: none

$ clang --version
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

更新

按照建议,我通过关注thisthis 页面并将CHPL_TARGET_COMPILER=gnu 添加到~/.chplconfig(在运行make 之前)从源代码安装了Chapel。然后,上述所有三个案例都运行了约 4 秒。因此,问题可能与 OSX10.11 上的 clang 有关。根据 cmets,较新的 OSX (>= 10.12) 没有此问题,因此升级到较新的 OSX/clang (>= 9.0) 可能就足够了。仅供参考,更新的环境信息(使用 GNU)如下:

$ printchplenv --anonymize
CHPL_TARGET_PLATFORM: darwin
CHPL_TARGET_COMPILER: gnu +
CHPL_TARGET_ARCH: native
CHPL_LOCALE_MODEL: flat
CHPL_COMM: none
CHPL_TASKS: qthreads
CHPL_LAUNCHER: none
CHPL_TIMERS: generic
CHPL_UNWIND: none
CHPL_MEM: jemalloc
CHPL_MAKE: make
CHPL_ATOMICS: intrinsics
CHPL_GMP: none
CHPL_HWLOC: hwloc
CHPL_REGEXP: none
CHPL_WIDE_POINTERS: struct
CHPL_AUX_FILESYS: none

【问题讨论】:

  • 您确定在所有情况下都使用了 --fast 吗?在您描述的所有 3 种情况下,我始终得到大约 4 秒,但如果我离开 --fast 则为 11 秒。
  • 是的,我刚刚用 --fast 选项重新尝试了所有三种情况,但它可以在我的 mac 上重现(顺便说一下,我在问题中使用了 -o a.out,但是这不影响结果)。如果这在其他环境中无法重现,可能是由于我自己的环境...
  • 我似乎在我的 Mac 上看到了类似于这个问题所报告的减速(尽管幅度略有不同)。但是,没有关于原因的理论。未注释的行应该会增加一些开销,但我不希望它们增加秒数/将执行时间加倍。
  • 如果我将 CHPL_TARGET_COMPILER 从“clang”切换到“gnu”,差异就会消失。我怀疑在 clang 编译级别发生了一些有趣的事情......
  • 当我试图重现这个时,我使用的是 OSX 10.12 和 clang 9.0。看起来clang版本差异解释了它。

标签: chapel


【解决方案1】:

我是否遗漏了上述代码中的某些内容(例如,错误地使用了 Timer)?

不,您没有遗漏任何东西,并且以完全合理的方式使用 Timer(和 Chapel)。根据我自己的实验(证实了您的实验,并在您的问题下的 cmets 中注明),这看起来是后端编译器问题,而不是 Chapel 或您使用它的基本问题。

【讨论】:

    【解决方案2】:

    [--fast] 减少了运行时检查,但 not the issue may re-run here

    还请注意,设置/操作附加开销有多大,
    仅用于教育目的
    (尝试并发处理),这使得 forall-构造函数配备 Atomics .add() 方法,积累了很多更高的开销,而不是并发处理所允许的增益,因为在启用[PAR] 的进程部分内的计算非常小(ref. newly re-formulated Amdahl's Law 在这些太薄的 [PAR]-gains v /s 确实对 [SEQ]-costs 的附加开销太高了。

    一个典型的消息。

    use Time;
    var timer = new Timer();
    
    config const n = 10**9;
             var s = 0.0, x = 0.0;
             var AtomiX: atomic real;                           // [AtomiX]______
                 AtomiX.write( 0.0 );                           // [AtomiX]______
    
    timer.start();                                              // [1]_____
    
    for k in 0 .. n {
        s  = ( if k % 2 == 0 then 1.0 else -1.0 );     // (-1)^k
        x += s / ( 2.0 * k + 1.0 );
    }
    
    /* forall k in 0..n { AtomiX.add( ( if k % 2 == 0 then 1.0 else -1.0 )
                                    / ( 2.0 * k + 1.0 )
                                      ); } */                   // [AtomiX]______
    
    timer.stop();                                               // [2]_____
    writeln( "time = ", timer.elapsed() );                      // [3]_____
    
       writef( "pi (approx) = %30.20dr\n", 4 * x );    
    // writef( "pi (approx) = %30.20dr\n", 4 * AtimiX.read() ); // [AtomiX]______
    // writef( "pi (exact)  = %30.20dr\n", pi );                // [4]_____
    
    /*
    --------------------------------------------------- [--fast] // AN EMPTY RUN
    time = 1e-06
    
    Real time:  9.582 s
    User time:  8.479 s
    Sys. time:  0.591 s
    CPU share: 94.65 %
    Exit code: 0
    --------------------------------------------------- [--fast] // all commented
    
    pi (approx) =         3.14159265458805059268
    
    Real time: 15.553 s
    User time: 13.484 s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~> Timer ~ +/- 1 second ( O/S noise )
    Sys. time:  0.985 s
    CPU share: 93.03 %
    Exit code: 0
    -------------------------------------------------- [--fast ] // Timer-un-commented
    time = 5.30128
    time = 5.3329
    pi (approx) =         3.14159265458805059268
    
    Real time: 14.356 s
    User time: 13.047 s ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< Timer ~ +/- 1 second ( O/S noise )
    Sys. time:  0.585 s
    CPU share: 94.95 %
    Exit code: 0
    
    Real time: 16.804 s
    User time: 14.853 s
    Sys. time:  0.925 s
    CPU share: 93.89 %
    Exit code: 0
    
    -------------------------------------------------- [--fast] // Timer-un-commented + forall + Atomics
    
    time = 14.7406
    pi (approx) =         3.14159265458805680993
    
    Real time: 28.099 s
    User time: 26.246 s
    Sys. time: 0.914 s
    CPU share: 96.65 %
    Exit code: 0
    */
    

    【讨论】:

    • 非常感谢,看来是我自己环境的问题还是什么的……我以后也会尝试在我的Linux机器上运行它(因为我现在无权访问)。
    • 对于如此微小的工作负载的任何基准测试来说,O/S 噪音是一个明显的敌人。一些重新运行可能会更好地显示这一点,但在过于嘈杂的背景下的主要问题仍然存在。
    猜你喜欢
    • 2017-09-18
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    相关资源
    最近更新 更多