差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
softwares:nestdaq:cplusplus [2024/01/23 13:23] – [型を調べる] kobayashsoftwares:nestdaq:cplusplus [2024/02/02 16:19] (現在) – [std::chrono ライブラリ] kobayash
行 1: 行 1:
 ===== NestDAQ C++ techniques ===== ===== 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 )+  * 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 )
 ==== 検証に使ったコード ==== ==== 検証に使ったコード ====
   * https://github.com/nobukoba/std_chrono_coding_sandbox   * https://github.com/nobukoba/std_chrono_coding_sandbox
  
 ==== 型を調べる ==== ==== 型を調べる ====
-  * std::chrono ライブラリなどのライブラリを使っていると、型がよくわからなくなっていくる。ウェブで調べるのも良いが、コード中では、調べ方がいくつかあるようだ。Clang++ だと、typeid(parameter).name() として、結果を c++filt -t コマンドに渡すと、プラグラムで使われている型がどんな型かわかる。<code>+  * 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 で走らせた結果。<code>### 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():
 +typeid(std::chrono::system_clock::period::den).name():
 +std::chrono::system_clock::period::num:
 +std::chrono::system_clock::period::den: 1000000000
 </code> </code>
 ==== std::chrono ライブラリ ==== ==== std::chrono ライブラリ ====
   * 時間、時刻関係の標準ライブラリ。C++11 から採用された模様。Boost からマージされたんだろうか?   * 時間、時刻関係の標準ライブラリ。C++11 から採用された模様。Boost からマージされたんだろうか?
-  * +  * Apple の環境だと、std::chrono::duration の period がマイクロ秒であるが、Linux では、ナノ秒になっている。これにより、nano秒単位にキャストしているコードにおいて、Linux でコンパイルが通っても、macOS で通らないことがある。 
 +  * 参考: Stack Overflow -- Apple clang: Why can I not create a time_point from std::chrono::nanoseconds https://stackoverflow.com/questions/65397041/apple-clang-why-can-i-not-create-a-time-point-from-stdchrononanoseconds 
 +  * 参考: Stack Overflow -- platform-specific std::chrono::high_resolution_clock::period::num https://stackoverflow.com/questions/47687645/platform-specific-stdchronohigh-resolution-clockperiodnum 
 +  * 参考: Stack Overflow -- Different behaviour of system_clock on windows and linux https://stackoverflow.com/questions/55120594/different-behaviour-of-system-clock-on-windows-and-linux 
 +=== std::chrono ライブラリクロックの違い === 
 +  * 以下のようなコードを書く<code> 
 +#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; 
 +
 +</code> 
 +  * macOS 12.3.1 でシステムの時計をずらせるように、network の時刻同期を切る。<code> 
 +$ 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 
 +</code> 
 +  * macOS 12.3.1 上でコードを実行する。<code>$ ./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 
 +</code> 
 +  * コードを実行中に、別の端末で、コードの実行開始時間より前の時間にシステムの時刻を変更する。<code> 
 +$ 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 
 +</code> 
 +  * その後、テストコードの出力を見ると、system_clock_duration.count()がマイナスの値になるが、steady_cklock と high_resolustion_clockは影響されない。<code> 
 +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 
 +</code> これをみると、std::chrono::high_resolution_clock は std::chrono::steady_clock の別名のようだ。また、Ubuntu MATE 22.03.3 LTS で実行すると、以下のようになる。<code> 
 +$ ./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 
 +... 
 +</code> これを見ると、std::chrono::high_resolution_clock は std::chrono::system_clock の別名のようだ。 
 + 
 + 
 +==== Arrow operator (->) in the function declaration ==== 
 +  * nestdaq/plugins/TimeUtil.h と TimeUtil.cxx で以下の書き方を見た。<code> 
 +auto update_date(const std::chrono::system_clock::time_point &s, 
 +                 const std::chrono::steady_clock::time_point &t) 
 +-> const std::pair<std::chrono::nanoseconds, std::chrono::system_clock::time_point>; 
 +</code> この関数を宣言している部分の 矢印 (->) は、関数の戻り値の型を定義しているようだ。 
 +    * 参考: https://stackoverflow.com/questions/22514855/arrow-operator-in-function-heading 
 +    * 参考: https://stackoverflow.com/questions/4113365/what-does-mean-in-c/4113390#4113390
softwares/nestdaq/cplusplus.1705983788.txt.gz · 最終更新: 2024/01/23 13:23 by kobayash
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0