2015年11月30日 星期一

MPI Three-Group Pipeline

底下的MPI範例很有趣, 來自於5.6.3. Inter-Communication Examples
它主要是想要介紹建立三個節點, 彼此之間使用communicator串起來, 模擬成pipeline的運作方式.
希望產的效果如下圖:

程式碼我有動過, 如下
//http://www.mpi-forum.org/docs/mpi-1.1/mpi-11-html/node114.html
//Groups 0 and 1 communicate. Groups 1 and 2 communicate.
//Therefore, group 0 requires one inter-communicator, group 1 requires two inter-communicators,
//and group 2 requires 1 inter-communicator.

//int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)
//int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm)
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char **argv){
        MPI_Comm   myComm;       /* intra-communicator of local sub-group */
        MPI_Comm   myFirstComm;  /* inter-communicator */
        MPI_Comm   mySecondComm; /* second inter-communicator (group 1 only) */
        int membershipKey = 0, rank =0, buffer = 0;
        MPI_Status status;
        double start_time, recive_time;

        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);

        /* User code must generate membershipKey in the range [0, 1, 2] */
        membershipKey = rank % 3;
        start_time = MPI_Wtime();

        /* Build intra-communicator for local sub-group */
        MPI_Comm_split(MPI_COMM_WORLD, membershipKey, rank, &myComm);

        /* Build inter-communicators.  Tags are hard-coded. */
        if (membershipKey == 0){
                /* Group 0 communicates with group 1. */
                MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 1, 1, &myFirstComm);
        }
        else if (membershipKey == 1){
                /* Group 1 communicates with groups 0 and 2. */
                MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 0, 1, &myFirstComm);
                MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 2, 12, &mySecondComm);
        }
        else if (membershipKey == 2){
                /* Group 2 communicates with group 1. */
                MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 1, 12, &mySecondComm);
        }

        switch(membershipKey){
                case 0:
                        buffer = 100;
                        printf("[%d][%f]buffer=%d\n", rank, MPI_Wtime() - start_time, buffer);
                        MPI_Send(&buffer, 1, MPI_INT, 0, 0, myFirstComm);
                        MPI_Recv(&buffer, 1, MPI_INT, 0, 0, myFirstComm, &status);
                        printf("[%d][%f]buffer=%d\n", rank, MPI_Wtime() - start_time, buffer);
                        break;
                case 1:
                        printf("[%d][%f]buffer=%d\n", rank, MPI_Wtime() - start_time, buffer);
                        MPI_Recv(&buffer, 1, MPI_INT, 0, 0, myFirstComm, &status);
                        printf("[%d][%f]buffer=%d\n", rank, MPI_Wtime() - start_time, buffer);
                        buffer = 200;
                        MPI_Send(&buffer, 1, MPI_INT, 0, 0, myFirstComm);
                        MPI_Send(&buffer, 1, MPI_INT, 0, 0, mySecondComm);
                        break;
                case 2:
                        MPI_Recv(&buffer, 1, MPI_INT, 0, 0, mySecondComm, &status);
                        printf("[%d][%f]buffer=%d\n", rank, MPI_Wtime() - start_time, buffer);
                        break;
        }

        MPI_Comm_free(&myComm);
        switch(membershipKey){/* free communicators appropriately */
                case 1:
                        MPI_Comm_free(&mySecondComm);
                        MPI_Comm_free(&myFirstComm);
                        break;
                case 0:
                        MPI_Comm_free(&myFirstComm);
                        break;
                case 2:
                        MPI_Comm_free(&mySecondComm);
                        break;
        }
        MPI_Finalize();
}
執行的結果如下
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
[0] Ending MPI_Init
[0] Starting MPI_Comm_rank...
[0] Ending MPI_Comm_rank
[0] Starting MPI_Comm_split...
[0] Ending MPI_Comm_split
[0] Starting MPI_Intercomm_create...
[0] Ending MPI_Intercomm_create
[0][0.000326]buffer=100
[0] Starting MPI_Send with count = 1, dest = 0, tag = 0...
[0] Ending MPI_Send
[0] Starting MPI_Recv with count = 1, source = 0, tag = 0...
[0] Ending MPI_Recv from 0 with tag 0
[0][0.000408]buffer=200
[0] Starting MPI_Comm_free...
[1] Ending MPI_Init
[1] Starting MPI_Comm_rank...
[1] Ending MPI_Comm_rank
[1] Starting MPI_Comm_split...
[1] Ending MPI_Comm_split
[1] Starting MPI_Intercomm_create...
[1] Ending MPI_Intercomm_create
[1] Starting MPI_Intercomm_create...
[1] Ending MPI_Intercomm_create
[1][0.000166]buffer=0
[1] Starting MPI_Recv with count = 1, source = 0, tag = 0...
[1] Ending MPI_Recv from 0 with tag 0
[1][0.000214]buffer=100
[1] Starting MPI_Send with count = 1, dest = 0, tag = 0...
[1] Ending MPI_Send
[1] Starting MPI_Send with count = 1, dest = 0, tag = 0...
[1] Ending MPI_Send
[1] Starting MPI_Comm_free...
[1] Ending MPI_Comm_free
[1] Starting MPI_Comm_free...
[2] Ending MPI_Init
[2] Starting MPI_Comm_rank...
[2] Ending MPI_Comm_rank
[2] Starting MPI_Comm_split...
[2] Ending MPI_Comm_split
[2] Starting MPI_Intercomm_create...
[2] Ending MPI_Intercomm_create
[0] Ending MPI_Comm_free
[0] Starting MPI_Comm_free...
[0] Ending MPI_Comm_free
[0] Starting MPI_Finalize...
[0] Ending MPI_Finalize
[1] Ending MPI_Comm_free
[1] Starting MPI_Comm_free...
[1] Ending MPI_Comm_free
[1] Starting MPI_Finalize...
[2] Starting MPI_Recv with count = 1, source = 0, tag = 0...
[2] Ending MPI_Recv from 0 with tag 0
[2][0.000409]buffer=200
[2] Starting MPI_Comm_free...
[2] Ending MPI_Comm_free
[2] Starting MPI_Comm_free...
[2] Ending MPI_Comm_free
[2] Starting MPI_Finalize...
[1] Ending MPI_Finalize
[2] Ending MPI_Finalize

改變vim程式碼註解的顏色

vim裏面程式碼註解的顏色預設值為深藍色.每次看註解都看到眼睛快花掉了.
還是改一下換個顏色.
vim ~/.vimrc
加入底下的命令
hi Comment ctermfg=cyan

效果如下圖:

你也可以試其它的顏色:
*cterm-colors*

NR-16   NR-8    COLOR NAME 
0       0       Black
1       4       DarkBlue
2       2       DarkGreen
3       6       DarkCyan
4       1       DarkRed
5       5       DarkMagenta
6       3       Brown, DarkYellow
7       7       LightGray, LightGrey, Gray, Grey
8       0*      DarkGray, DarkGrey
9       4*      Blue, LightBlue
10      2*      Green, LightGreen
11      6*      Cyan, LightCyan
12      1*      Red, LightRed
13      5*      Magenta, LightMagenta
14      3*      Yellow, LightYellow
15      7*      White

2015年11月28日 星期六

sscanf in C language

這個是Jack給的一個有趣程式, 以底下的範例來說
輸入的字串可是是"
#include <string.h>
#include <stdio.h>
int main(int argc, char** argv){
        int b[5] = {0, 0, 0, 0, 0};
        int ret;

        if(argc == 2){
                ret = sscanf( argv[1], "%d,%d,%d,%d,%d\n", &b[0], &b[1], &b[2], &b[3], &b[4]);
                printf("ret = %d, b0=%d b1=%d b2=%d b3=%d b4=%d\n", ret, b[0], b[1], b[2], b[3], b[4] );
        }
}


執行狀況如下:
./test

./test 1
ret = 1, b0=1 b1=0 b2=0 b3=0 b4=0

./test 1,2
ret = 2, b0=1 b1=2 b2=0 b3=0 b4=0

./test 1,2,3
ret = 3, b0=1 b1=2 b2=3 b3=0 b4=0

./test 1,2,3,4
ret = 4, b0=1 b1=2 b2=3 b3=4 b4=0

./test 1,2,3,4,5
ret = 5, b0=1 b1=2 b2=3 b3=4 b4=5

./test 1,2,3,4,5,6
ret = 5, b0=1 b1=2 b2=3 b3=4 b4=5


sscanf的函式宣告型態如下
int sscanf(const char *str, const char *format, ...);
使用它時需要
#include <stdio.h>

MPI_Bcast

MPI_Bcast廣播函式, 這個是一個很有趣的功能. 將要變更的資料變數及內容傳送給其它的接收

/* C Example */
#include <mpi.h>
#include <stdio.h>

int main (int argc, char* argv[]){
        int rank, size;
        double t1;
        void *v;
        int flag;
        int mytable[1] = { 0 };

        MPI_Init (&argc, &argv);      /* starts MPI */
        MPI_Comm_rank (MPI_COMM_WORLD, &rank);        /* get current process id */
        MPI_Comm_size (MPI_COMM_WORLD, &size);        /* get number of processes */
        t1 = MPI_Wtime();
        MPI_Attr_get( MPI_COMM_WORLD, MPI_WTIME_IS_GLOBAL, &v, &flag );
        printf( "Hello world from process %d of %d, time = %f, global time = %d\n", rank, size, MPI_Wtime() - t1, flag);

        mytable[0] = rank + 100;
        MPI_Barrier(MPI_COMM_WORLD);
        MPI_Bcast(&mytable[0], 1, MPI_INT, atoi(argv[1]), MPI_COMM_WORLD);
        printf("%d/%d: mytable[0] = %d\n", rank, size, mytable[0]);
        MPI_Barrier(MPI_COMM_WORLD);

        MPI_Finalize();
        return 0;
}
mpirun -np 5 ./bcast 0執行結果1
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
[0] Ending MPI_Init
[0] Starting MPI_Comm_rank...
[0] Ending MPI_Comm_rank
[0] Starting MPI_Comm_size...
[0] Ending MPI_Comm_size
[0] Starting MPI_Attr_get...
[0] Ending MPI_Attr_get
Hello world from process 0 of 5, time = 0.000011, global time = 1
[0] Starting MPI_Barrier...
[0] Ending MPI_Barrier
[0] Starting MPI_Bcast...
[0] Starting MPI_Bcast with count = 1
[0] Ending MPI_Bcast
0/5: mytable[0] = 100
[0] Starting MPI_Barrier...
[0] Ending MPI_Barrier
[0] Starting MPI_Finalize...
[0] Ending MPI_Finalize
[1] Ending MPI_Init
[1] Starting MPI_Comm_rank...
[1] Ending MPI_Comm_rank
[1] Starting MPI_Comm_size...
[1] Ending MPI_Comm_size
[1] Starting MPI_Attr_get...
[1] Ending MPI_Attr_get
Hello world from process 1 of 5, time = 0.000012, global time = 1
[1] Starting MPI_Barrier...
[1] Ending MPI_Barrier
[1] Starting MPI_Bcast...
[1] Starting MPI_Bcast with count = 1
[1] Ending MPI_Bcast
1/5: mytable[0] = 100
[1] Starting MPI_Barrier...
[1] Ending MPI_Barrier
[1] Starting MPI_Finalize...
[1] Ending MPI_Finalize
[2] Ending MPI_Init
[2] Starting MPI_Comm_rank...
[2] Ending MPI_Comm_rank
[2] Starting MPI_Comm_size...
[2] Ending MPI_Comm_size
[2] Starting MPI_Attr_get...
[2] Ending MPI_Attr_get
Hello world from process 2 of 5, time = 0.000012, global time = 1
[2] Starting MPI_Barrier...
[2] Ending MPI_Barrier
[2] Starting MPI_Bcast...
[2] Starting MPI_Bcast with count = 1
[2] Ending MPI_Bcast
2/5: mytable[0] = 100
[2] Starting MPI_Barrier...
[2] Ending MPI_Barrier
[2] Starting MPI_Finalize...
[3] Ending MPI_Init
[3] Starting MPI_Comm_rank...
[3] Ending MPI_Comm_rank
[3] Starting MPI_Comm_size...
[3] Ending MPI_Comm_size
[3] Starting MPI_Attr_get...
[3] Ending MPI_Attr_get
Hello world from process 3 of 5, time = 0.000010, global time = 1
[3] Starting MPI_Barrier...
[3] Ending MPI_Barrier
[3] Starting MPI_Bcast...
[3] Starting MPI_Bcast with count = 1
[3] Ending MPI_Bcast
3/5: mytable[0] = 100
[3] Starting MPI_Barrier...
[3] Ending MPI_Barrier
[3] Starting MPI_Finalize...
[4] Ending MPI_Init
[4] Starting MPI_Comm_rank...
[4] Ending MPI_Comm_rank
[4] Starting MPI_Comm_size...
[4] Ending MPI_Comm_size
[4] Starting MPI_Attr_get...
[4] Ending MPI_Attr_get
Hello world from process 4 of 5, time = 0.000009, global time = 1
[4] Starting MPI_Barrier...
[4] Ending MPI_Barrier
[4] Starting MPI_Bcast...
[4] Starting MPI_Bcast with count = 1
[4] Ending MPI_Bcast
4/5: mytable[0] = 100
[4] Starting MPI_Barrier...
[4] Ending MPI_Barrier
[4] Starting MPI_Finalize...
[2] Ending MPI_Finalize
[3] Ending MPI_Finalize
[4] Ending MPI_Finalize
mpirun -np 5 ./bcast 1執行結果2
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
[0] Ending MPI_Init
[0] Starting MPI_Comm_rank...
[0] Ending MPI_Comm_rank
[0] Starting MPI_Comm_size...
[0] Ending MPI_Comm_size
[0] Starting MPI_Attr_get...
[0] Ending MPI_Attr_get
Hello world from process 0 of 5, time = 0.000017, global time = 1
[0] Starting MPI_Barrier...
[0] Ending MPI_Barrier
[0] Starting MPI_Bcast...
[0] Starting MPI_Bcast with count = 1
[0] Ending MPI_Bcast
0/5: mytable[0] = 101
[0] Starting MPI_Barrier...
[0] Ending MPI_Barrier
[0] Starting MPI_Finalize...
[1] Ending MPI_Init
[1] Starting MPI_Comm_rank...
[1] Ending MPI_Comm_rank
[1] Starting MPI_Comm_size...
[1] Ending MPI_Comm_size
[1] Starting MPI_Attr_get...
[1] Ending MPI_Attr_get
Hello world from process 1 of 5, time = 0.000010, global time = 1
[1] Starting MPI_Barrier...
[1] Ending MPI_Barrier
[1] Starting MPI_Bcast...
[1] Starting MPI_Bcast with count = 1
[1] Ending MPI_Bcast
1/5: mytable[0] = 101
[1] Starting MPI_Barrier...
[1] Ending MPI_Barrier
[1] Starting MPI_Finalize...
[1] Ending MPI_Finalize
[2] Ending MPI_Init
[2] Starting MPI_Comm_rank...
[2] Ending MPI_Comm_rank
[2] Starting MPI_Comm_size...
[2] Ending MPI_Comm_size
[2] Starting MPI_Attr_get...
[2] Ending MPI_Attr_get
Hello world from process 2 of 5, time = 0.000008, global time = 1
[2] Starting MPI_Barrier...
[2] Ending MPI_Barrier
[2] Starting MPI_Bcast...
[2] Starting MPI_Bcast with count = 1
[2] Ending MPI_Bcast
2/5: mytable[0] = 101
[2] Starting MPI_Barrier...
[2] Ending MPI_Barrier
[2] Starting MPI_Finalize...
[3] Ending MPI_Init
[3] Starting MPI_Comm_rank...
[3] Ending MPI_Comm_rank
[3] Starting MPI_Comm_size...
[3] Ending MPI_Comm_size
[3] Starting MPI_Attr_get...
[3] Ending MPI_Attr_get
Hello world from process 3 of 5, time = 0.000008, global time = 1
[3] Starting MPI_Barrier...
[3] Ending MPI_Barrier
[3] Starting MPI_Bcast...
[3] Starting MPI_Bcast with count = 1
[3] Ending MPI_Bcast
3/5: mytable[0] = 101
[3] Starting MPI_Barrier...
[3] Ending MPI_Barrier
[3] Starting MPI_Finalize...
[4] Ending MPI_Init
[4] Starting MPI_Comm_rank...
[4] Ending MPI_Comm_rank
[4] Starting MPI_Comm_size...
[4] Ending MPI_Comm_size
[4] Starting MPI_Attr_get...
[4] Ending MPI_Attr_get
Hello world from process 4 of 5, time = 0.000009, global time = 1
[4] Starting MPI_Barrier...
[4] Ending MPI_Barrier
[4] Starting MPI_Bcast...
[4] Starting MPI_Bcast with count = 1
[4] Ending MPI_Bcast
4/5: mytable[0] = 101
[4] Starting MPI_Barrier...
[4] Ending MPI_Barrier
[4] Starting MPI_Finalize...
[0] Ending MPI_Finalize
[2] Ending MPI_Finalize
[3] Ending MPI_Finalize
[4] Ending MPI_Finalize

MPI_Wtime

突然發現, 原來MPI有提供一個函式MPI_Wtime(), 可以用來計算運行過的時間, 單位是秒.
它的回傳值是double, 並且需要確定你的系統環境是MPI_WTIME_IS_GLOBAL是有被定義的.
/* C Example */
#include <mpi.h>
#include <stdio.h>

int main (int argc, char* argv[]){
        int rank, size;
        double t1;
        void *v;
        int flag;

        MPI_Init (&argc, &argv);      /* starts MPI */
        MPI_Comm_rank (MPI_COMM_WORLD, &rank);        /* get current process id */
        MPI_Comm_size (MPI_COMM_WORLD, &size);        /* get number of processes */
        t1 = MPI_Wtime();
        MPI_Attr_get( MPI_COMM_WORLD, MPI_WTIME_IS_GLOBAL, &v, &flag );
        printf( "Hello world from process %d of %d, time = %f, global time = %d\n", rank, size, MPI_Wtime() - t1, flag);
        MPI_Finalize();
        return 0;
}

MPI & MPE Helloworld

這次來介紹MPI搭配MPE(MPI Parallel Environment)來tracing程式的運作
主程式hello.c跟先前的相同, 程式碼如下:
/* C Example */
#include <mpi.h>
#include <stdio.h>

int main (int argc, char* argv[])
{
  int rank, size;

  MPI_Init (&argc, &argv);      /* starts MPI */
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);        /* get current process id */
  MPI_Comm_size (MPI_COMM_WORLD, &size);        /* get number of processes */
  printf( "Hello world from process %d of %d\n", rank, size );
  MPI_Finalize();
  return 0;
}
Makefile內容如下:
all:
        mpecc -mpitrace -o hello hello.c

mpirun -np 5 ./hello 執行的結果如下:
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
Starting MPI_Init...
[0] Ending MPI_Init
[0] Starting MPI_Comm_rank...
[0] Ending MPI_Comm_rank
[0] Starting MPI_Comm_size...
[0] Ending MPI_Comm_size
Hello world from process 0 of 5
[0] Starting MPI_Finalize...
[0] Ending MPI_Finalize
[1] Ending MPI_Init
[1] Starting MPI_Comm_rank...
[1] Ending MPI_Comm_rank
[1] Starting MPI_Comm_size...
[1] Ending MPI_Comm_size
Hello world from process 1 of 5
[1] Starting MPI_Finalize...
[1] Ending MPI_Finalize
[2] Ending MPI_Init
[2] Starting MPI_Comm_rank...
[2] Ending MPI_Comm_rank
[2] Starting MPI_Comm_size...
[2] Ending MPI_Comm_size
Hello world from process 2 of 5
[2] Starting MPI_Finalize...
[3] Ending MPI_Init
[3] Starting MPI_Comm_rank...
[3] Ending MPI_Comm_rank
[3] Starting MPI_Comm_size...
[3] Ending MPI_Comm_size
Hello world from process 3 of 5
[3] Starting MPI_Finalize...
[4] Ending MPI_Init
[4] Starting MPI_Comm_rank...
[4] Ending MPI_Comm_rank
[4] Starting MPI_Comm_size...
[4] Ending MPI_Comm_size
Hello world from process 4 of 5
[4] Starting MPI_Finalize...
[2] Ending MPI_Finalize
[3] Ending MPI_Finalize
[4] Ending MPI_Finalize

2015年11月26日 星期四

Brillo Toybox

大概瞄了一下, 突然發現, system/bin/裏面不是裝busybox也不是裝toolbox了.改成用toybox了.
原來AOSP已經改用toybox了, 看起來這轉換的過程也歷經了許多的故事.
有興趣的可以看一下Android gets a toybox.

底下這張圖是brillo裏/system/bin的檔案列表.
.
├── bin
│   ├── acpi -> toybox
│   ├── apmanager
│   ├── applypatch_static
│   ├── audio_hal_playback_test
│   ├── audio_hal_record_test
│   ├── avahi-browse
│   ├── avahi-daemon
│   ├── base64 -> toybox
│   ├── basename -> toybox
│   ├── bdt
│   ├── blockdev -> toybox
│   ├── bluetooth-cli
│   ├── bluetoothtbd
│   ├── bootctl
│   ├── brillo_audio_test
│   ├── bzcat -> toybox
│   ├── cal -> toybox
│   ├── cat -> toybox
│   ├── chcon -> toybox
│   ├── check_prereq
│   ├── chgrp -> toybox
│   ├── chmod -> toybox
│   ├── chown -> toybox
│   ├── chroot -> toybox
│   ├── cjpeg
│   ├── cksum -> toybox
│   ├── clear -> toybox
│   ├── cmp -> toybox
│   ├── comm -> toybox
│   ├── core2md
│   ├── cp -> toybox
│   ├── cpio -> toybox
│   ├── crash_reporter
│   ├── crash_sender
│   ├── curl
│   ├── cut -> toybox
│   ├── date -> toybox
│   ├── dbus-daemon
│   ├── dbus-example-client
│   ├── dbus-example-daemon
│   ├── dbus-send
│   ├── dd -> toolbox
│   ├── df -> toybox
│   ├── dhcpcd
│   ├── dhcpcd-6.8.2
│   ├── dhcptool
│   ├── dirname -> toybox
│   ├── djpeg
│   ├── dmesg -> toybox
│   ├── dnsmasq
│   ├── dos2unix -> toybox
│   ├── du -> toybox
│   ├── echo -> toybox
│   ├── egrep -> grep
│   ├── env -> toybox
│   ├── expand -> toybox
│   ├── expr -> toybox
│   ├── fallocate -> toybox
│   ├── false -> toybox
│   ├── ff_debug
│   ├── fgrep -> grep
│   ├── find -> toybox
│   ├── firewalld
│   ├── flash_image
│   ├── flock -> toybox
│   ├── free -> toybox
│   ├── gdbserver
│   ├── getenforce -> toybox
│   ├── getevent -> toolbox
│   ├── getprop -> toybox
│   ├── grep
│   ├── groups -> toybox
│   ├── head -> toybox
│   ├── hostapd
│   ├── hostapd_cli
│   ├── hostname -> toybox
│   ├── hwclock -> toybox
│   ├── id -> toybox
│   ├── ifconfig -> toybox
│   ├── iftop -> toolbox
│   ├── initnetwork.sh
│   ├── inotifyd -> toybox
│   ├── insmod -> toybox
│   ├── ioctl -> toolbox
│   ├── ionice -> toybox
│   ├── iorenice -> toybox
│   ├── iotop
│   ├── ip
│   ├── ip6tables
│   ├── ip6tables-restore -> ip6tables
│   ├── ip6tables-save -> ip6tables
│   ├── iptables
│   ├── iptables-restore -> iptables
│   ├── iptables-save -> iptables
│   ├── iw
│   ├── keystore
│   ├── keystore_cli
│   ├── keystore_cli_v2
│   ├── kill -> toybox
│   ├── killall -> toybox
│   ├── linker
│   ├── ln -> toybox
│   ├── load_policy -> toybox
│   ├── log -> toolbox
│   ├── logcat
│   ├── logd
│   ├── logname -> toybox
│   ├── logpersist.cat -> logpersist.start
│   ├── logpersist.start
│   ├── logpersist.stop -> logpersist.start
│   ├── losetup -> toybox
│   ├── ls -> toybox
│   ├── lsmod -> toybox
│   ├── lsof -> toybox
│   ├── lsusb -> toybox
│   ├── md5sum -> toybox
│   ├── mediaserver
│   ├── memory_replay32
│   ├── metrics_client
│   ├── metrics_daemon
│   ├── mkdir -> toybox
│   ├── mknod -> toybox
│   ├── mkswap -> toybox
│   ├── mktemp -> toybox
│   ├── modinfo -> toybox
│   ├── more -> toybox
│   ├── mount -> toybox
│   ├── mountpoint -> toybox
│   ├── mv -> toybox
│   ├── nandread -> toolbox
│   ├── nativepowerman
│   ├── netstat -> toybox
│   ├── newfs_msdos -> toolbox
│   ├── nice -> toybox
│   ├── nl -> toybox
│   ├── nohup -> toybox
│   ├── od -> toybox
│   ├── paste -> toybox
│   ├── patch -> toybox
│   ├── periodic_scheduler
│   ├── pgrep -> toybox
│   ├── pidof -> toybox
│   ├── ping
│   ├── pkill -> toybox
│   ├── pmap -> toybox
│   ├── postinst_example
│   ├── power_example
│   ├── printenv -> toybox
│   ├── printf -> toybox
│   ├── prlimit -> toolbox
│   ├── ps -> toolbox
│   ├── pwd -> toybox
│   ├── r
│   ├── readlink -> toybox
│   ├── realpath -> toybox
│   ├── reboot
│   ├── renice -> toybox
│   ├── restorecon -> toybox
│   ├── rm -> toybox
│   ├── rmdir -> toybox
│   ├── rmmod -> toybox
│   ├── rootdev
│   ├── route -> toybox
│   ├── runcon -> toybox
│   ├── sed -> toybox
│   ├── sendevent -> toolbox
│   ├── sensorservice
│   ├── sensors-hal-example-app
│   ├── sensors-ndk-example-app
│   ├── seq -> toybox
│   ├── servicemanager
│   ├── setenforce -> toybox
│   ├── setprop -> toybox
│   ├── setsid -> toybox
│   ├── sh
│   ├── sha1sum -> toybox
│   ├── shill
│   ├── showlease
│   ├── sleep -> toybox
│   ├── slesTest_playFdPath
│   ├── slesTest_recBuffQueue
│   ├── slesTest_sawtoothBufferQueue
│   ├── sort -> toybox
│   ├── split -> toybox
│   ├── start -> toolbox
│   ├── stat -> toybox
│   ├── stop -> toolbox
│   ├── strings -> toybox
│   ├── swapoff -> toybox
│   ├── swapon -> toybox
│   ├── sync -> toybox
│   ├── sysctl -> toybox
│   ├── tac -> toybox
│   ├── tail -> toybox
│   ├── tar -> toybox
│   ├── taskset -> toybox
│   ├── tee -> toybox
│   ├── time -> toybox
│   ├── timeout -> toybox
│   ├── tlsdate
│   ├── tlsdated
│   ├── tlsdate-helper
│   ├── toolbox
│   ├── top -> toolbox
│   ├── touch -> toybox
│   ├── toybox
│   ├── tr -> toybox
│   ├── tracepath
│   ├── tracepath6
│   ├── traceroute6
│   ├── true -> toybox
│   ├── truncate -> toybox
│   ├── tty -> toybox
│   ├── umount -> toybox
│   ├── uname -> toybox
│   ├── uniq -> toybox
│   ├── unix2dos -> toybox
│   ├── update_engine
│   ├── update_engine_client
│   ├── updater
│   ├── uptime -> toybox
│   ├── usleep -> toybox
│   ├── vmstat -> toybox
│   ├── wc -> toybox
│   ├── weaved
│   ├── webservd
│   ├── which -> toybox
│   ├── whoami -> toybox
│   ├── wifi_init
│   ├── wpa_cli
│   ├── wpa_debug
│   ├── wpa_supplicant
│   ├── xargs -> toybox
│   ├── xxd -> toybox
│   └── yes -> toybox

一個小故事讓我們明白資金流通的意義

“又是炎熱小鎮慵懶的一天。太陽高掛,街道無人,每個人都債台高築,靠信用度日。這時,從外地來了一位有錢的旅客,他進了一家旅館,拿出一張1000 元鈔票放在櫃檯,說想先看看房間,挑一間合適的過夜,就在此人上樓的時候---- 店主抓了這張1000 元鈔,跑到隔壁屠戶那裡支付了他欠的肉錢...