メモの日々


2001年01月19日(金) ケーキを頂いた

ドコモの営業の人と顔合わせ。DoPaのルータのアドレスを変更するのだ。準備が足りず、何も話せず。

トークに手書きをどう入れ込めばいいかを考えたが、難しい。うまくいかんのと違うか?

[dev] 特別公開!アーキテクチャドキュメント

オージス総研が作った設計書を見れる。RUPで規定しているドキュメントのようだ。

freemlの広告

freeml.comはメイルの最後に広告が入るのだ。で、メイルにファイルを添付すると添付ファイルのさらに後ろに広告が入っていて、メイルリーダの画面には広告が表示されない。添付ファイルとしても表示されないが、メイルをベタで見ると確かに広告が最後に付いているのだ。


2004年01月19日(月)

[c] GDBによるテスト自動化への試み (ファイヤープロジェクト)

あうあう、よさそう。やはりGDBにもっと慣れ親しまねば。今日のなんでやねんより。

生活

  • セマフォのプログラミング。イヤーって感じ。
  • 今日の行数:2124

やること

  • 靴紐を買う
  • 電球を買う
  • WindowsUpdate(職場)

2009年01月19日(月)

[dev][howto] svn:ignore の設定方法

svn:ignore の設定方法をすぐに忘れるのでメモ。

svn propedit svn:ignore ディレクトリ名

を実行するとエディタが起動するので、そこに無視リストを改行区切りで入力し、保存終了してcommitすれば設定完了。

svn propget svn:ignore ディレクトリ名

で、そのディレクトリに設定してあるsvn:ignoreの値を参照できる。

svn propdel svn:ignore ディレクトリ名

で、そのディレクトリに設定してあるsvn:ignoreを削除できるのだと思う。使ったことない。

svn:ignore はSubversionに管理対象外のファイルを教えるための属性で、指定するとsvn statusの出力がすっきりする。ディレクトリ毎に設定する。サブディレクトリには伝播してくれないので、必要ならば各ディレクトリにいちいち個別に設定する必要があるみたい。

なお、リポジトリに保存するのではなくクライアント環境ローカルで無視リストを管理したい場合は、global-ignores が使える。これは以前にメモしている。

参考

  • svn:ignore (Subversion によるバージョン管理)
  • svn propedit (Subversion によるバージョン管理)

2012年01月19日(木)

  • なかなか眠れない日が続いて困っている。眠いのだけれど眠れない。

[howto][unix][shell] uniqの-cオプションである列の文字列の出現回数を数える

定番だけど、uniqコマンドのの-cオプションが便利なので自分でメモ。

/var/log/messages.1 の5列目に出現する文字列の中で出現回数の多いものを得る例。

% cut -d \  -f 5 /var/log/messages.1 | sort | uniq -c | sort -n | tail
      4 sendmail:
      4 yum:
      6 dhclient:
      8 udevd[1775]:
     10 sysctl:
     10 vtune:
     11 smartd[6945]:
     13 ntpd[7057]:
     14 rc.sysinit:
    609 kernel:

参考


2023年01月19日(木)

[c++] OpenMPのサンプル

OpenMPの使い方を毎回忘却してしまうので例をメモしておく。

並列に偶数のvectorを構築する例。

#include <iostream>
#include <vector>

#include <omp.h>

std::vector<int> make_vector(int size)
{
  std::vector<int> result;

  #pragma omp parallel
  {
    std::vector<int> local;

    #pragma omp for nowait
    for (int i = 0; i < size; ++i) {
      if (i % 2 == 0) local.push_back(i);
    }

    #pragma omp critical
    result.insert(result.end(), local.begin(), local.end());
  }

  return result;
}

int main()
{
  const auto max_threads = omp_get_max_threads();
  std::cout << "max_threads = " << max_threads << std::endl;

  const auto v = make_vector(max_threads * 10);

  std::cout << "v.size = " << v.size() << std::endl;
  for (auto e : v) {
    std::cout << e << ", ";
  }
  std::cout << std::endl;
}
max_threads = 6
v.size = 30
0, 2, 4, 6, 8, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 30, 32, 34, 36, 38, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,
  • コンパイル時にOpenMPの使用を明示する必要がある。GCCの場合は-fopenmpオプションを付与する。
  • #pragma omp parallelのあるブロックはマルチスレッドで実行される。ブロック内で宣言された変数はスレッドローカルな変数になる。ブロックの外で宣言された変数はスレッド間で共有する変数になる(のでアクセス時に排他制御が必要)。
  • #pragma omp forのあるforループはスレッド間で分担して実行される。デフォルトではループの末尾で全スレッドが待ち合わせるが、nowaitを指定すると待ち合せなくなる。
  • #pragma omp criticalのあるブロックはスレッド間で排他的に実行される。

上の例のmake_vector()は、#pragma omp declare reductionを使ってリダクション識別子を宣言すると明示的にcriticalを指定せずに書くことができる。ただ、コードが分かりにくくなるので積極的に使うべきかは微妙。

#pragma omp declare reduction ( \
  concat :  \
  std::vector<int> :  \
  omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end()) \
)

std::vector<int> make_vector(int size)
{
  std::vector<int> result;

  #pragma omp parallel for reduction(concat: result)
  for (int i = 0; i < size; ++i) {
    if (i % 2 == 0) result.push_back(i);
  }

  return result;
}
  • concatという、vectorを結合するリダクション識別子を宣言した。その内容を定義する際にはomp_inとomp_outという識別子を使うと決まっている。
  • 宣言したリダクション識別子は、ディレクティブのreduction節で使用する。reduction節ではリダクション識別子にスレッド間の共有変数(上の例ではresult)を適用する。
    • これにより、当該ブロック内での当該共有変数に対する操作はスレッドローカルに行われるようになる。
    • ブロックを抜ける際に、スレッドローカルな値が共有変数へ定義したリダクション内容で反映される。
    • (と理解した)
  • #pragma omp parallel forは最初の例で使った #pragma omp parallel と #pragma omp for をまとめた処理を行う。criticalを使わなくてよくなるのでこのディレクティブを使える。