NestDAQ C++ techniques

  • NestDAQ では開発者のコーディング量削減のため、Boost ライブラリといった便利な外部ライブラリ、さらに C++11 以上で採用された便利な機能が多く使われている。そのため、それなりに新しい C++ の書き方に慣れておく必要がある。個人的には、プログラミング初学者の可読性を考慮し、CERN ROOT v5 のインタープリター程度でつかえていた機能しか普段は使っていないので、なかなか覚えるのが大変。最近は new / delete を使わず、スマートポインタとかを使わないといけないらしい。(参考: servernote.net –【C++】new/deleteを撤廃しstd::shared_ptrを使う https://www.servernote.net/article.cgi?id=cpp-std-shared-ptr )

検証に使ったコード

型を調べる

  • std::chrono ライブラリなどのライブラリを使っていると、型がよくわからなくなっていくる。ウェブで調べるのも良いが、コード中では、調べ方がいくつかあるようだ。Clang++ だと、typeid(parameter).name() として、結果を c++filt -t コマンドに渡すと、プラグラムで使われている型がどんな型かわかる。以下、std::chrono の場合の確認用プログラム ( https://github.com/nobukoba/std_chrono_coding_sandbox/blob/f7f4b4db501db0b9b0aaab640c513e16c325d511/std_chrono_multi_platforms.cc ) を Ubuntu MATE 22.04.3 LTS で走らせた結果。
    ### Parameter definitions ###
    std::chrono::system_clock::time_point  p_time_point;
    std::chrono::system_clock::duration    p_duration;
    std::chrono::system_clock::period      p_period;
    
    ### typeid().name() results ###
    typeid(p_time_point).name(): NSt6chrono10time_pointINS_3_V212system_clockENS_8durationIlSt5ratioILl1ELl1000000000EEEEEE
    typeid(p_duration  ).name(): NSt6chrono8durationIlSt5ratioILl1ELl1000000000EEEE
    typeid(p_period    ).name(): St5ratioILl1ELl1000000000EE
    
    ### c++filt -t results ###
    c++filt -t typeid(p_time_point).name(): 
    std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >
    c++filt -t typeid(p_duration).name(): 
    std::chrono::duration<long, std::ratio<1l, 1000000000l> >
    c++filt -t typeid(p_period).name(): 
    std::ratio<1l, 1000000000l>
    
    ### system_clock::period::num and den check ###
    typeid(std::chrono::system_clock::period::num).name(): l
    typeid(std::chrono::system_clock::period::den).name(): l
    std::chrono::system_clock::period::num: 1
    std::chrono::system_clock::period::den: 1000000000

std::chrono ライブラリ

std::chrono ライブラリクロックの違い

  • 以下のようなコードを書く
    #include <iostream>
    #include <thread>
    #include <chrono>
    
    int main(int argc,char *argv[]){
      std::chrono::system_clock::time_point          system_clock_start = std::chrono::system_clock::now();
      std::chrono::steady_clock::time_point          steady_clock_start = std::chrono::steady_clock::now();
      std::chrono::high_resolution_clock::time_point h_reso_clock_start = std::chrono::high_resolution_clock::now();
      std::chrono::nanoseconds system_clock_start_epoch = std::chrono::duration_cast<std::chrono::nanoseconds> (system_clock_start.time_since_epoch());
      std::chrono::nanoseconds steady_clock_start_epoch = std::chrono::duration_cast<std::chrono::nanoseconds> (steady_clock_start.time_since_epoch());
      std::chrono::nanoseconds h_reso_clock_start_epoch = std::chrono::duration_cast<std::chrono::nanoseconds> (h_reso_clock_start.time_since_epoch());
    
      for (int i = 0; i < 100; i++) {
        std::chrono::system_clock::time_point          system_clock_now = std::chrono::system_clock::now();
        std::chrono::steady_clock::time_point          steady_clock_now = std::chrono::steady_clock::now();
        std::chrono::high_resolution_clock::time_point h_reso_clock_now = std::chrono::high_resolution_clock::now();
        std::chrono::nanoseconds system_clock_now_epoch = std::chrono::duration_cast<std::chrono::nanoseconds> (system_clock_now.time_since_epoch());
        std::chrono::nanoseconds steady_clock_now_epoch = std::chrono::duration_cast<std::chrono::nanoseconds> (steady_clock_now.time_since_epoch());
        std::chrono::nanoseconds h_reso_clock_now_epoch = std::chrono::duration_cast<std::chrono::nanoseconds> (h_reso_clock_now.time_since_epoch());
        std::chrono::nanoseconds system_clock_duration  = std::chrono::duration_cast<std::chrono::nanoseconds> (system_clock_now - system_clock_start);
        std::chrono::nanoseconds steady_clock_duration  = std::chrono::duration_cast<std::chrono::nanoseconds> (steady_clock_now - steady_clock_start);
        std::chrono::nanoseconds h_reso_clock_duration  = std::chrono::duration_cast<std::chrono::nanoseconds> (h_reso_clock_now - h_reso_clock_start);
        
    
        std::time_t now = std::chrono::system_clock::to_time_t(system_clock_now);
        std::string s(30, '\0');
        std::strftime(&s[0], s.size(), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
    
        std::cout << "system_clock_now: " << s << std::endl;
        std::cout << "system_clock_now_epoch.count(): " << system_clock_now_epoch.count() << std::endl;
        std::cout << "steady_clock_now_epoch.count(): " << steady_clock_now_epoch.count() << std::endl;
        std::cout << "h_reso_clock_now_epoch.count(): " << h_reso_clock_now_epoch.count() << std::endl;
        std::cout << "system_clock_duration.count(): "  << system_clock_duration.count() << std::endl;
        std::cout << "steady_clock_duration.count(): "  << steady_clock_duration.count() << std::endl;
        std::cout << "h_reso_clock_duration.count(): "  << h_reso_clock_duration.count() << std::endl;
        std::cout << std::endl;
    
        std::this_thread::sleep_for(std::chrono::seconds(1));
      }
      return 0;
    }
  • macOS 12.3.1 でシステムの時計をずらせるように、network の時刻同期を切る。
    $ sudo systemsetup -setusingnetworktime off
    2024-02-02 15:09:51.126 systemsetup[23124:12338196] ### Error:-99 File:/AppleInternal/Library/BuildRoots/66382bca-8bca-11ec-aade-6613bcf0e2ee/Library/Caches/com.apple.xbs/Sources/Admin/InternetServices.m Line:379
    setUsingNetworkTime: Off
  • macOS 12.3.1 上でコードを実行する。
    $ ./std_chrono_comp_clocks 
    system_clock_now: 2024-02-02 15:56:02
    system_clock_now_epoch.count(): 1706856962044809000
    steady_clock_now_epoch.count(): 3446501139918415
    h_reso_clock_now_epoch.count(): 3446501139918476
    system_clock_duration.count(): 3000
    steady_clock_duration.count(): 2728
    h_reso_clock_duration.count(): 2706
    
    system_clock_now: 2024-02-02 15:56:03
    system_clock_now_epoch.count(): 1706856963050483000
    steady_clock_now_epoch.count(): 3446502145634015
    h_reso_clock_now_epoch.count(): 3446502145634132
    system_clock_duration.count(): 1005677000
    steady_clock_duration.count(): 1005718328
    h_reso_clock_duration.count(): 1005718362
    
    system_clock_now: 2024-02-02 15:56:04
    system_clock_now_epoch.count(): 1706856964055087000
    steady_clock_now_epoch.count(): 3446503150279622
    h_reso_clock_now_epoch.count(): 3446503150279705
    system_clock_duration.count(): 2010281000
    steady_clock_duration.count(): 2010363935
    h_reso_clock_duration.count(): 2010363935
  • コードを実行中に、別の端末で、コードの実行開始時間より前の時間にシステムの時刻を変更する。
    $ sudo systemsetup -settime 15:56:00
    2024-02-02 15:56:00.000 systemsetup[24235:12388285] ### Error:-99 File:/AppleInternal/Library/BuildRoots/66382bca-8bca-11ec-aade-6613bcf0e2ee/Library/Caches/com.apple.xbs/Sources/Admin/InternetServices.m Line:379
    Set Time: 15:56:00
  • その後、テストコードの出力を見ると、system_clock_duration.count()がマイナスの値になるが、steady_cklock と high_resolustion_clockは影響されない。
    system_clock_now: 2024-02-02 15:56:01
    system_clock_now_epoch.count(): 1706856961000765000
    steady_clock_now_epoch.count(): 3446504154296655
    h_reso_clock_now_epoch.count(): 3446504154296770
    system_clock_duration.count(): -1044041000
    steady_clock_duration.count(): 3014380968
    h_reso_clock_duration.count(): 3014381000
    
    system_clock_now: 2024-02-02 15:56:02
    system_clock_now_epoch.count(): 1706856962003841000
    steady_clock_now_epoch.count(): 3446505157415128
    h_reso_clock_now_epoch.count(): 3446505157415217
    system_clock_duration.count(): -40965000
    steady_clock_duration.count(): 4017499441
    h_reso_clock_duration.count(): 4017499447
    
    system_clock_now: 2024-02-02 15:56:03
    system_clock_now_epoch.count(): 1706856963007809000
    steady_clock_now_epoch.count(): 3446506161423906
    h_reso_clock_now_epoch.count(): 3446506161423991
    system_clock_duration.count(): 963003000
    steady_clock_duration.count(): 5021508219
    h_reso_clock_duration.count(): 5021508221

    これをみると、std::chrono::high_resolution_clock は std::chrono::steady_clock の別名のようだ。また、Ubuntu MATE 22.03.3 LTS で実行すると、以下のようになる。

    $ ./std_chrono_comp_clocks 
    system_clock_now: 2024-02-02 16:18:15
    system_clock_now_epoch.count(): 1706858295484039608
    steady_clock_now_epoch.count(): 1109260620490710
    h_reso_clock_now_epoch.count(): 1706858295484039845
    system_clock_duration.count(): 1217
    steady_clock_duration.count(): 958
    h_reso_clock_duration.count(): 945
    
    system_clock_now: 2024-02-02 16:18:16
    system_clock_now_epoch.count(): 1706858296484348873
    steady_clock_now_epoch.count(): 1109261620800102
    h_reso_clock_now_epoch.count(): 1706858296484349263
    system_clock_duration.count(): 1000310482
    steady_clock_duration.count(): 1000310350
    h_reso_clock_duration.count(): 1000310363
    
    system_clock_now: 2024-02-02 16:18:17
    system_clock_now_epoch.count(): 1706858297484600085
    steady_clock_now_epoch.count(): 1109262621051266
    h_reso_clock_now_epoch.count(): 1706858297484600429
    system_clock_duration.count(): 2000561694
    steady_clock_duration.count(): 2000561514
    h_reso_clock_duration.count(): 2000561529
    ...

    これを見ると、std::chrono::high_resolution_clock は std::chrono::system_clock の別名のようだ。

Arrow operator (->) in the function declaration

softwares/nestdaq/cplusplus.txt · 最終更新: 2024/02/02 16:19 by kobayash
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0