windows7のセットアップ

インストールしたアプリ

ショートカットの設定

C:\ProgramData\Microsoft\Windows\Start Menu\Programsにjumpという名前でフォルダを作成。

フォルダ以下にショートカットを置くと、スターとメニューでショートカットが起動できる。

フォルダのショートカットの設定

C:\ProgramData\Microsoft\Windows\Start Menu\Programsにある適当なショートカットをコピーして、右クリック->プロパティを開く。

ショートカットのリンク先を以下のように設定。

C:\Windows\explorer.exe dir_path

dir_pathは、開きたいディレクトリのパス。

作業フォルダは適当に設定する。

thinkpad E450で削除したプリインストールアプリなど

削除したプリインストールアプリは以下。

参考

Lenovo ThinkPad のスタートアッププログラム・常駐プログラムについての詳細 - 情報科学屋さんを目指す人のメモ(FC2ブログ版)

  • SHAREit

    • dropboxみたいに何かシェアする
  • REACHit

    • dropboxなどのweb上のシステムに一括でアクセスできるようなもの
  • lenovo auto scroll utility

  • Message center plus

  • lenovo peer connect sdk

  • lenovo usb3.0 to dvi vba monitor adapter

    • usbでDVI/VGAモニターにつなぐアダプターのためのドライバ?
  • lenovo Quickcontrol

  • lenovo solution center

  • lenovo communications utility

  • thinkVantage active protection system(SSD換装後)

    • HDDを落下時の衝撃などから守る
  • マカフィー リブセーフ インターネットセキュリティ

PCの設定

  • タッチパッドの無効化

    • [コントロールパネル]->[マウス]->[ThinkPad]タブ->TouchPadの無効化

E450マニュアル等

製品仕様書

ThinkPad E450 製品仕様書 - 20DC005EJP,20DC005FJP,20DC005GJP,20DC005HJP | Lenovo | 日本

裏蓋の外し方、メモリの増設仕方などのマニュアル。 「ハードウェア保守マニュアル ThinkPad E450」で検索

ハードウェア保守マニュアル ThinkPad E450 - Google 検索

セットアップ手順

  1. リカバリメディアの作成

  2. SSDの換装とメモリの増設

  3. SSDとメモリのテスト

  4. windowsをリカバリメディアから復帰

リカバリメディアの作成

OS別手順

リカバリー方法 - Lenovo Support (JP)

Win7

リカバリー・メディアの作成方法 - Windows 7 - Lenovo Support (JP)

リカバリメディア用USB

Amazon CAPTCHA

SSDへの換装

E450用のマニュアル

ThinkPadのSSD換装~準備編 - Thinkpad E450の気になる話

ThinkPadのSSD換装~作業編 - Thinkpad E450の気になる話

ThinkPad E450のSSD換装手順はとっても簡単でした。

換装用SSD

Amazon CAPTCHA

Amazon.co.jp: Crucial [Micron製Crucialブランド] MX100シリーズ ( 512GB / 2.5インチ / SSD ) 国内正規品 CT512MX100SSD1: パソコン・周辺機器

メモリの増設

購入時は、DDR3L PC3L-12800 4GBの一枚差し、空きスロットは1。省電力用のDDR3L PC3Lなので注意。

ThinkPad E450 Review #2 裏蓋外し(JP) | Jibara de Review

増設用メモリ

価格.com - ADATA ADDS1600W4G11-R [SODIMM DDR3L PC3L-12800 4GB] 価格比較

リカバリメディアからの復帰

USBからbootする場合はBIOSでF12

ThinkPad E450のSSD換装手順はとっても簡単でした。

awkで偶数行目を取り出しと指定した数の倍数行に処理を追加

奇数行、偶数行を取り出す処理は、perlワンライナーであったり、sedだったり色々あるが、今回はawkでの処理を記載。

cat filename.txt | awk 'NR % 2 == 0 {print $0;}'

偶数行目のみを取り出して、5の倍数行に改行を2つ入れる処理は以下のようにする。

cat filename.txt | awk 'NR % 2 == 0 {print $0;}' | awk 'NR % 5 != 0 {print $0;} NR % 5 == 0{print $0;print "\n"}' 

boost::numeric::ublas::vectorの速度比較

boost/numeric/ublas/vectorの生成と代入に関する速度をまとめた。

素数を5千万にして生成と代入の速度を計測。

compiler及び環境

clock関数で時間を計測。時間の分解能はμ秒。

時間はコンパイル時にO2オプションをつけた時と付けない時の時間を記載。

生成と初期化の速度

まとめ

  • ublas::vectorstd::vectorの生成に関する時間の差はなし。

  • vectorのfor文での全要素の走査は生成の6倍程度の時間がかかる。但し、O2オプションをつければ生成と同程度の時間ですむ。

    • 生成後の代入操作はなるべく避ける。

std::vectorの生成の時間

std::vector<double> vec1(num, 2.0);

上記コードのstd::vectorの生成の時間は

  • O2なし:0.379705[sec]
  • O2あり:0.244777[sec]

boost::numeric::ublas::vectorの生成の時間

boost::numeric::ublas::vector<double> vec3(num, 1.2);

上記コードのboost::numeric::ublas::vectorの生成の時間

  • O2なし:0.408235[sec]
  • O2あり:0.249085[sec]

boost::numeric::ublas::vectorの走査時間

    for (std::size_t index = 0; index < num; ++index) {
        vec3[index] = index / 2.0;
    }

上記コードのboost::numeric::ublas::vectorの走査時間

  • O2なし:1.27493[sec]
  • O2あり:O2:0.279947[sec]

代入に関する時間

前提として下記コード内のvec2,vec3は以下のように要素数5千万のublas::vectorとして宣言されているとする。

const std::size_t num = 50000000;
boost::numeric::ublas::vector<double> vec2(num);
boost::numeric::ublas::vector<double> vec3(num);

まとめ

  • vec2=vec3の代入が最も高速。

  • for文での要素毎の代入はvec2=vec3の4倍程度かかる。

  • 関数への参照渡しは要素数にかかわらずほぼ時間0と考えて良い。

  • 関数への実体渡しは、vectorの生成にかかる時間と同程度かやや遅い。

  • 関数への実体戻しでの代入は、for文での代入と同じくらい遅い。

  • 参照渡しで関数内でvec2=vec3をするのと、関数外でvec2=vec3は速度はほぼ同じ。

vec2=vec3の速度

    vec3[1] = vec2[10];
    vec2 = vec3;
    vec2[1] = vec3[2];
  • O2なし:0.079151
  • O2あり:0.075633

for文による要素毎の代入の速度速度

    for (std::size_t index = 0; index < num; ++index) {
        vec2[index] = vec3[index];
    }
  • O2なし:1.83324
  • O2あり:0.3431

生成のときのfor文の倍の時間かかっているのは、operator[]が二個あるため。

関数の参照渡しと戻り値を実体戻し

boost::numeric::ublas::vector<double> hoge(
    boost::numeric::ublas::vector<double>& vec)
{
    return vec;
}
    vec3 = hoge(vec2);
  • O2なし:0.408114
  • O2あり:0.317184

for文と同じくらい遅い

関数の参照渡しと参照戻し

boost::numeric::ublas::vector<double>& hoge2(
    boost::numeric::ublas::vector<double>& vec)
{
    return vec;
}
    vec3 = hoge2(vec2);
   
  • O2なし:0.073233
  • O2あり:0.075371

おそらく、vec2=vec3と内部的には同じ動作。

参照渡しにかかる時間

void hoge3(
    boost::numeric::ublas::vector<double>& vec)
{
}
    hoge3(vec3);
  • O2なし:1e-06
  • O2あり:0

参照渡しにかかる時間はほぼゼロ。O2で0[sec]になっているのはおそらく関数内にコードがないので、関数呼び出しを省略されたため。

関数の実体渡しにかかる時間

void hoge4(
    boost::numeric::ublas::vector<double> vec)
{
}
    hoge4(vec3);
  • O2なし:0.264846
  • O2あり:0.249281

実体渡しは生成とほぼ同じ時間がかかる。

参照渡しで関数内でvec2=vec3

void hoge5(
    boost::numeric::ublas::vector<double>& vec,
    boost::numeric::ublas::vector<double>& vec2)
{
    vec2 = vec;
}
    hoge5(vec2, vec3);
  • O2なし:0.075753
  • O2あり:0.074778

コード全体

時間は時間計測開始部分にコメントで以下のように付与している。

//O2オプションなしの時間[sec]
//O2オプションありの時間[sec]
start = clock()
//処理など
#include <boost/numeric/ublas/vector.hpp>
#include <vector>

#include <time.h>

boost::numeric::ublas::vector<double> hoge(
    boost::numeric::ublas::vector<double>& vec)
{
    return vec;
}

boost::numeric::ublas::vector<double>& hoge2(
    boost::numeric::ublas::vector<double>& vec)
{
    return vec;
}

void hoge3(
    boost::numeric::ublas::vector<double>& vec)
{
}

void hoge4(
    boost::numeric::ublas::vector<double> vec)
{
}

void hoge5(
    boost::numeric::ublas::vector<double>& vec,
    boost::numeric::ublas::vector<double>& vec2)
{
    vec2 = vec;
}

int main(int argc, char const* argv[])
{
    namespace ublas = boost::numeric::ublas;
    
    const std::size_t num = 50000000;

    //0.379705
    //O2:0.244777
    clock_t start = clock();
    std::vector<double> vec1(num, 2.0);
    clock_t end = clock();
    double duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration1:" << duraiton << std::endl;

    boost::numeric::ublas::vector<double> vec2(num, 1.0);
    for (std::size_t index = 0; index < num; ++index) {
        vec2[index] = index;
    }

    //0.408235
    //O2:0.249085
    start = clock();
    boost::numeric::ublas::vector<double> vec3(num, 1.2);
    end = clock();
    duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration2:" << duraiton << std::endl;
    //1.27493
    //O2:0.279947
    start = clock();
    for (std::size_t index = 0; index < num; ++index) {
        vec3[index] = index / 2.0;
    }
    end = clock();
    duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration3:" << duraiton << std::endl;

    //0.118211
    //O2:0.103219
    start = clock();
    vec3[1] = vec2[10];
    vec2 = vec3;
    vec2[1] = vec3[2];
    end = clock();
    duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration4:" << duraiton << std::endl;

    //2.2732
    //O2:0.446582
    start = clock();
    for (std::size_t index = 0; index < num; ++index) {
        vec2[index] = vec3[index];
    }
    end = clock();
    duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration5:" << duraiton << std::endl;

    //0.422054
    //O2:0.421855
    start = clock();
    vec3 = hoge(vec2);
    end = clock();
    duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration6:" << duraiton << std::endl;

    //0.119685
    //O2:0.115396
    start = clock();
    vec3 = hoge2(vec2);
    end = clock();
    duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration7:" << duraiton << std::endl;
    
    //1e-06
    //O2:0
    start = clock();
    hoge3(vec3);
    end = clock();
    duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration8:" << duraiton << std::endl;

    //0.346663
    //O2:0.259321
    start = clock();
    hoge4(vec3);
    end = clock();
    duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration9:" << duraiton << std::endl;

    //0.074641
    //O2:0.075302
    start = clock();
    hoge5(vec2, vec3);
    end = clock();
    duraiton = static_cast<double>((end - start)) / CLOCKS_PER_SEC;
    std::cout << "duration10:" << duraiton << std::endl;

    
    return 0;
}

C++のclassとstructの違い

はっきりとした言及があまりなかったので一応メモ。

Cにおいてclassとstructは(Cには記憶クラスというものがあって)全くの別物だが、C++ではstructとclassに機能的な違いはない。

structとclassの違い

振る舞いとしての唯一の違いはデフォルトのアクセス指定子の違いである。

  • struct
    • デフォルトでpublic
  • class
    • デフォルトでprivate
struct hoge{
    int h;
};
class hage {
    int h;
};

int main() {
    hoge hoge_instance;
    hage hage_instance;
    
    hoge_instance.h = 1; //OK
    //hage_instance.h = 1; //NG 
    return 0;
}

次のように書けば等価

struct hoge{
public://かかなくても良いが
    int h;
};
class hage {
public:
    int h;
};

int main() {
    hoge hoge_instance;
    hage hage_instance;
    
    hoge_instance.h = 1; //OK
    hage_instance.h = 1; //OK
    return 0;
}

structとclassの使い分け

以下に使い分けに関して言及がある。

oop - What are the differences between struct and class in C++? - Stack Overflow

要点をまとめると

  • 機能的な違いはないからどちらを使ってもOK
  • 使い分けとして広く浸透しているものを明示的にのべるなら
    • structは機能が少ないものやカプセル化が殆どされてない(publicなメンバ変数、関数のみ)な場合に使用される
    • classは良く設計されたインターフェースを持ち、カプセル化がされており、洗練された機能を提供する場合に使用される
  • 具体的には、数個のメソッドとpublicな変数をもつ場合はstruct
  • 上記のようなカプセル化がされて(して)ないクラスは、十分に良く設計されたシステムにおいても存在しうる。

C++のstaticに関するまとめ

static(メンバ)変数への代入について知識がうろ覚えだったので、整理した。要点は以下。

  1. staticな変数は宣言と同時に代入する
  2. staticなstruct型の初期化は{}で行う.
  3. class内のstaticなメンバに代入するときはクラスの宣言の外で代入.また型の指定が必要.
  4. class内struct型がprivateに宣言されていてもクラスの外で初期化できる
  5. class templateのstaticなメンバ変数、関数への代入はtemplateを指定する
  6. staticな関数ポインタはtemplate関数で初期化できる

前提知識1

前提知識として関数ポインタの宣言は以下のようにする。

引数名は省略可能。

戻り値 (*変数名)(引数型1 引数名1, 引数型2 引数名2, 続く)
void (*hensu_mei)(void* hoge, double* hage);

前提知識2

c++struct型とclassは(メンバの宣言がデフォルトでpublicかどうかの違いはあるが)基本的に区別がない。

1. staticな変数は宣言と同時に代入する

よくみる構文なので当たり前だが、後述のstaticメンバの初期化とはちょっと異なるのに注意がいる。

/******************************************************************************
 * staticな変数は宣言と同時に代入.
 ******************************************************************************/
void static_test_f0(void*) {
}
static void (*static_test_fp)(void *) = static_test_f0; //OK

//static void (*static_test_fp)(void* hoge);
//static_test_fp = static_test_f0; //NG

2. staticなstruct型の初期化は{}で行う.

staticなstruct型の場合。{}記号の一つの用法。

/******************************************************************************
 * staticなstruct型の初期化は{}で行う.
 ******************************************************************************/

void static_class_test_f(void *) {
}

struct static_class_test {
    void (*test)(void *);
    double hoge;
};

static struct static_class_test static_class_test_instance =  {
    static_class_test_f,
    1.0
};

3. class内のstaticなメンバに代入するときはクラスの宣言の外で代入. また型の指定が必要.

staticな変数のとの大きな違いは下記。 * staticの宣言と代入を別の場所で行う * 型の指定が必要になる

/******************************************************************************
 * class内のstaticなメンバに代入するときはクラスの宣言の外で代入.
 * また型の指定が必要.
 ******************************************************************************/
void static_test_f1(void*) {
}
class static_test1 {
public:
    static_test1() {};

    static void (*test)(void *);
    //static void (*test)(void *) = static_test_f1; //NG
    //void (*test)(void *) = static_test_f1; //NG
    static double hoge;
    //static double hoge = 1.0; //NG
};

void (*static_test1::test)(void *) = static_test_f1;
//static_test1::test = static_test_f1; //NG
double static_test1::hoge = 1.0;
//static_test1::hoge = 1.0; //NG

4. class内struct型がprivateに宣言されていてもクラスの外で初期化できる

staticなstruct型のメンバも上記2と3の組み合わせで代入できる。

注意すべき点はstaticなstruct型がprivateなクラス内struct型であっても問題ないという所。

/******************************************************************************
 * class内struct型がprivateに宣言されていてもクラスの外で初期化できる
 ******************************************************************************/
class initialize_struct_test1 {
private:
    struct vtable {
        void (*draw)(void*);
        double hoge;
    };

public:
    initialize_struct_test1();
    static vtable _vTable;
};

void test1(void *hoge) {
    //initialize_struct_test1::vtable hage; //NG
}

initialize_struct_test1::vtable initialize_struct_test1::_vTable = {
    test1,
    2.0
};
//instaneがないので.は使えない
//void (*initialize_struct_test1::_vTable.test)(void*) = test2; //NG
//double initialize_struct_test1::_vTable.hoge = 2.0; //NG

5. class templateのstaticの時はtemplateも指定する

class templateにstaticなメンバがあるときはtemplateを指定して代入する。

/******************************************************************************
 * class templateのstaticの時はtemplateも指定する
 ******************************************************************************/
template <typename T>
class class_teplate_test {
public:
   class_teplate_test();

   static void (*test)(void*); 
   static double hoge;
};

void test2(void *hoge) {
}

template <typename T>
void (*class_teplate_test<T>::test)(void *) = test2;
template <typename T>
double class_teplate_test<T>::hoge = 10.0;

6. staticな関数ポインタはtemplate関数で初期化できる

staticな関数ポインタに限った話ではないが、template関数の用法。

/******************************************************************************
 * staticなtemplate関数はtemplateの指定が必要.
 ******************************************************************************/
template <typename T>
void template_func_test_f1(T*) {
}

void template_func_test_f2(int*) {
}

static void (*template_func_test)(char*) = template_func_test_f1;

//こういうのがやりたいならメタプログラミング
//template <typename T>
//static void (*template_func_test)(T*) = template_func_test_f2;

参考

C++の記号一覧 (List of C++ symbols) - gununuの日記