comparison Dec-2013/17th.html @ 5:a96eeacc9d7b

add
author Masataka Kohagura <e085726@ie.u-ryukyu.ac.jp>
date Tue, 17 Dec 2013 18:47:21 +0900
parents 104a8986166e
children 89f82b09e32c
comparison
equal deleted inserted replaced
4:3549c54cc7b7 5:a96eeacc9d7b
64 64
65 <article> 65 <article>
66 <h3> 66 <h3>
67 今週のしたこと 67 今週のしたこと
68 </h3> 68 </h3>
69 <p> 69 <ul>
70 ・検索文字列のハードコーディングの脱却<br> 70
71 </p> 71 <li>
72 read関数によるfileの順次読み込み<br>
73 (読み込み部分をread()からpread()へ変更)
74 </li>
75
76 <li>
77 Read Taskのブロック化
78 (1つずつ起動していたものを、ブロック単位で起動するようにした)
79 </li>
80
81 <li>
82 MapReduce関数の整理
83 </li>
84
85 <ul>
72 </article> 86 </article>
73 87
74 <!-- 88 <!--
75 <article class='smaller'> 89 <article class='smaller'>
76 <h3>I/O並列化のシーケンス図(mmap)</h3> 90 <h3>I/O並列化のシーケンス図(mmap)</h3>
91 --> 105 -->
92 106
93 107
94 <article> 108 <article>
95 109
110 <h3> readからpreadへ</h3>
111 <p>変更前</p>
112 <section><pre>
113 int *fd = (int *)s->get_input(rbuf,0); ///ファイルディスクリプタの受取
114 long readsize = (long)s->get_param(0);
115 long task_number = (long)s->get_param(1);
116
117 char text[(long)readsize];
118
119 <font color="red">read(*fd,text,(long)readsize);</font>
120
121 s->printf("[start task No. %d]\n",task_number);
122 s->printf("%s\n",text);
123 </pre></section>
124
125 <p>変更後</p>
126 <section><pre>
127 <font color="red">pread(*fd, text, (long)read_size , division_size*task_number);</font>
128 </pre></section>
129
130 </article>
131
132 <article class='smaller'>
96 <h3> 133 <h3>
97 main.cc:run_tasks内部(Taskへのデータ渡し) 134 pread
98 </h3> 135 </h3>
99 <section><pre> 136
100 Task *t_exec = 0; 137 <section><pre>
101 138 read(int fd, void *buf, size_t count);
102 t_exec = task_array->next_task_array(TASK_EXEC,t_exec);
103 t_exec->set_inData(0,w->file_mmap + a*w->division_size, size);
104 <font color="red">t_exec->set_inData(1,w->search_word, w->search_word_len);</font>
105 t_exec->set_inData(2,w->BMskip_table, 256);
106 </pre></section> 139 </pre></section>
107 140
108 <h3> 141 <section><pre>
109 ppe/Exec.cc(Task内でのデータの受取) 142 pread(int fd, void *buf, size_t count, <font color="red">off_t offset</font>);
110 </h3>
111 <section><pre>
112 unsigned char *i_data = (unsigned char *)s->get_input(rbuf,0);
113 <font color="red">unsigned char *search_word = (unsigned char *)s->get_input(rbuf,1);</font>
114 int *skip_table = (int *)s->get_input(2);
115
116 s->printf("[in Exec search word = %p\n",search_word);
117 </pre></section> 143 </pre></section>
118 144
145 <ul>
146 <li>
147 fd:ファイルディスクリプタ
148 </li>
149 <li>
150 buf:readするDataの格納領域
151 </li>
152 <li>
153 count:どれだけの量(byte)を読み込むか
154 </li>
155 <li>
156 offset:ファイルの先頭からどれだけの量(byte)を飛ばして読み込むのか
157 </li>
158 </ul>
159
160 <p>
161 read関数だと、Taskの起動する順番やタイミングによって同じ場所を読み込んだりしてしまう。read関数は読み込んだ後にファイルディスクリプタをずらしてしまうので、そのような現象が起こると考えられる。
162 </p>
163 <p>
164 pread関数だと、ファイルディスクリプタを動かさずにoffsetを取ることで読み込む場所が替えることができる。これだと、上記の現象が起こらずにすむ。
165 </p>
119 </article> 166 </article>
167
120 168
121 <article> 169 <article>
122 <h3> 170 <h3>
123 実行(アドレスの桁落ち(?))) 171 readでの読み込みの失敗例
124 </h3> 172 </h3>
125 <section><pre> 173 <section><pre>
126 ./regex -file c.txt -cpu 1 -sw doing 174 % ./fileread -file d.txt
127 in TMmain search_word = 0x7fba99c1a090 175 filesize : 16398
128 in run start search_word = 0x7fba99c1a090 176 one_task_size: 16384
129 in run tasks w->search_word = 0x7fba99c1a090 177 task_num : 2
130 <font color="red">in Exec search word = 0x99c1a090</font> 178 [start task No. 0]
131 zsh: segmentation fault ./regex -file c.txt -cpu 1 -sw doing 179 firstaaaaaaaaaaaaaaaaaaaaaa...16380
132 </pre></section> 180 doin
181 [start task No. 1]
182 firstaaaaaaaaa
183 </pre></section>
184
185 <section><pre>
186 [start task No. 0]
187 gxbaaabaaabab
188 [start task No. 1]
189 gxbaaabaaabab
190 </pre></section>
191 </article>
192
193 <article class='smaller'>
194 <h3>Read Taskのblock化</h3>
195 <p>変更前</p>
196 <section><pre>
197 run_start(TaskManager *manager,char *filename)
198 {
199 HTask *read;
200 int *fd = (int*)manager->allocate(sizeof(int));
201
202 if ((*fd=open(filename,O_RDONLY,0666))==0) {
203 fprintf(stderr,"can't open %s\n",filename);
204 }
205 ...
206
207 for(int task_number = 0; task_number < task_num; task_number++){
208 read = manager->create_task(READ_TASK);
209 read->set_cpu(spe_cpu);
210
211 [task settings(省略)]
212
213 }
214 }
215 </pre></section>
216 </article>
217
218 <article class='smaller'>
219 <p>変更後</p>
220 <section><pre>
221 run_start(TaskManager *manager,char *filename)
222 {
223 int *fd = (int*)manager->allocate(sizeof(int));
224
225 if ((*fd=open(filename,O_RDONLY,0666))==0) {
226 fprintf(stderr,"can't open %s\n",filename);
227 }
228
229 if (fstat(*fd,sb)) {
230 fprintf(stderr,"can't fstat %s\n",filename);
231 }
232 ...
233
234 FilereadPtr fr = (FilereadPtr)manager->allocate(sizeof(Fileread));
235
236 HTaskPtr run = manager->create_task(RUN_BLOCKS, (memaddr)&fr->self, sizeof(memaddr),0,0);
237 run->spawn();
238 }
239 </pre></section>
240 </article>
241
242 <article class='smaller'>
243 <p>RUN_BLOCKS</p>
244 <section><pre>
245 SchedDefineTask1(RUN_BLOCKS,run16);
246
247 run16(SchedTask *manager, void *in, void *out) {
248
249 FilereadPtr fr = (FilereadPtr)in;
250 HTaskPtr wait;
251
252 for (int i = 0; (fr->left_size > 0) && (i < fr->task_blocks); i++) {
253 HTaskPtr read = manager->create_task(Read_task);
254 read->set_cpu(fr->cpu);
255
256 if (i == fr->task_blocks / 2) wait = read;
257
258 [task settings(省略)]
259
260 }
261 return 0;
262 }
263 </pre></section>
133 264
134 <ul> 265 <ul>
135 <li> 266 <li>
136 search_word のアドレスが上の桁から落ちている。skip_table(intの配列)でもセグフォが発生するので、skip_tableももしかしたらアドレスが同じように落ちているんじゃ・・・ 267 Taskを1個1個起動ではなくブロック単位で起動している理由は、メモリの再利用のためである。
268 1個1個起動すると、その分のメモリが必要となり、Task数が多くなると肥大化する。
269 ブロック単位で起動することでメモリを節約するとともに、メモリの書き換えが少なくて済むので高速化につながる。
137 </li> 270 </li>
138 </ul> 271 </ul>
139 </article> 272 </article>
140 273
141 274
142 <article> 275 <article class='smaller'>
143 <h3> 276 <h3>Taskのブロック化の図(1)</h3>
144 ppe/Exec.ccの修正 277 <p>word countでの実装</p>
145 </h3> 278 <p>
146 <section><pre> 279 <div align="center">
147 unsigned char *i_data = <font color="red">(unsigned char *)s->get_inputAddr(0);</font> 280 <img src="images/old_run_task_blocks.jpg" width="40%" height="40%">
148 unsigned char *search_word = <font color="red">(unsigned char *)s->get_inputAddr(1);</font> 281 </div>
149 int *skip_table = <font color="red">(int *)s->get_inputAddr(2);</font> 282 </p>
150
151 s->printf("in Exec search_word : %p\n",search_word);
152 </pre></section>
153
154 <h3>
155 実行
156 </h3>
157 <section><pre>
158 ./regex -file c.txt -cpu 1 -sw doing
159 in run_tasks w->search_word Addr: 0x7f989b708280
160 in Exec search_word Addr : 0x7f989b708280
161 HIT:27856
162 Time: 0.042276
163 </pre></section>
164 <li>
165 get_inputAddrだと正しくアドレスを受け渡しすることができた。
166 </li>
167 </article>
168
169 <article>
170 <h3>これからのすること</h3>
171 <ul> 283 <ul>
172 <li> 284 <li>
173 シンヤさんのRegenのソース読み&実装 285 run16がブロック単位でTaskを起動する。word countでは48 Task/1block。
174 </li> 286 </li>
175 <li> 287 <li>
176 並列I/Oの実装<br> 288 ブロック内の処理が全て終わらないと、新しいブロックを生成することができない。<br>
177 (例題:filereadにてI/Oの分割読み込みのプログラムを実装) 289 すべてのTaskが終わるまで待つので、オーバヘッドが起こる。
290 </li>
291 </ul>
292 </article>
293
294 <article class='smaller'>
295 <h3>Taskのブロック化の図(2)</h3>
296 <p>filereadでの実装</p>
297 <div align="center">
298 <img src="images/new_run_task_blocks.jpg" width="40%" height="40%">
299 </div>
300 <ul>
301 <li>
178 </li> 302 </li>
179 </ul> 303 </ul>
180 </article> 304 </article>
181 305
182 </body> 306 </body>