Mercurial > hg > Papers > 2010 > kent-master
comparison quicksort_for_ppc/mc/quicksort_cbc.cbc @ 1:aa09c34b90d3
add quicksort_for_pcc
add sources, figures.
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 01 Feb 2010 20:37:36 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:e9ecd5b5f29a | 1:aa09c34b90d3 |
---|---|
1 #include<stdio.h> | |
2 #include<stdlib.h> | |
3 #include<assert.h> | |
4 | |
5 typedef void *stack; | |
6 typedef struct { | |
7 int size; | |
8 void *interface; | |
9 __code (*ret)(void*, stack) ; | |
10 } frame, *framep; | |
11 | |
12 /* quickstart main routine. */ | |
13 typedef struct { | |
14 int *v; | |
15 int s; | |
16 int e; | |
17 } QS_IF ; | |
18 typedef __code (*RET)(void*); | |
19 | |
20 #include"quicksort_cbc.h" | |
21 | |
22 /* for check. */ | |
23 void *mustbefreed; | |
24 | |
25 __code returner(stack sp) | |
26 { | |
27 framep fp = (framep)sp; | |
28 sp += fp->size; | |
29 goto fp->ret(fp->interface, sp); | |
30 } | |
31 | |
32 __code quicksort_start(void *arg, stack sp) | |
33 { | |
34 QS_IF *recvif = arg; | |
35 int a,b,c,p; | |
36 a = recvif->v[recvif->s]; | |
37 b = recvif->v[recvif->e]; | |
38 c = recvif->v[(recvif->s+recvif->e)/2]; | |
39 | |
40 //printf("quicksort_start: s=%d,e=%d", recvif->s, recvif->e); | |
41 if (recvif->e <= recvif->s) goto returner(sp); | |
42 | |
43 if (a < b) { | |
44 if (b < c) | |
45 p = b; | |
46 else if (a < c) | |
47 p = c; | |
48 else | |
49 p = a; | |
50 } else { | |
51 if (a < c) | |
52 p = a; | |
53 else if (b < c) | |
54 p = c; | |
55 else | |
56 p = b; | |
57 } | |
58 | |
59 goto quicksort_divider (recvif, recvif->s, recvif->e, p, sp); | |
60 } | |
61 /* main routine end. */ | |
62 | |
63 /* divide routine. */ | |
64 __code quicksort_divider(QS_IF *recvif, int s, int e, int p, stack sp) | |
65 { | |
66 goto quicksort_divider_s(recvif, s, e, p, sp); | |
67 } | |
68 __code quicksort_divider_s(QS_IF *recvif, int s, int e, int p, stack sp) | |
69 { | |
70 if (recvif->v[s]<p) { | |
71 goto quicksort_divider_s(recvif, s+1, e, p, sp); | |
72 } else | |
73 goto quicksort_divider_e(recvif, s, e, p, sp); | |
74 } | |
75 __code quicksort_divider_e(QS_IF *recvif, int s, int e, int p, stack sp) | |
76 { | |
77 if (p<recvif->v[e]) { | |
78 e--; | |
79 goto quicksort_divider_e(recvif, s, e, p, sp); | |
80 } else | |
81 goto quicksort_swapper(recvif, s, e, p, sp); | |
82 } | |
83 __code quicksort_swapper(QS_IF *recvif, int s, int e, int p, stack sp) | |
84 { | |
85 if (s<e) { | |
86 int tmp; | |
87 tmp = recvif->v[s]; | |
88 recvif->v[s] = recvif->v[e]; | |
89 recvif->v[e] = tmp; | |
90 goto quicksort_divider(recvif, s+1, e-1, p, sp); | |
91 } else { | |
92 goto quicksort_treecall(recvif, s, e, sp); | |
93 } | |
94 } | |
95 /* divide routin end. */ | |
96 | |
97 | |
98 /* recursive call routine. */ | |
99 __code quicksort_treecall(QS_IF *recvif, int s, int e, stack sp) | |
100 { | |
101 framep fp; | |
102 QS_IF *outif; | |
103 | |
104 /* interface for first quicksort_start this segment directly jump to. */ | |
105 outif = (sp-=sizeof(QS_IF)); | |
106 outif->v = recvif->v; | |
107 outif->s = recvif->s; | |
108 outif->e = e; | |
109 fp = (sp-=sizeof(frame)); | |
110 fp->ret = quicksort_start; | |
111 fp->interface = recvif; | |
112 fp->size = sizeof(frame)+sizeof(QS_IF); | |
113 | |
114 /* recvif is used by second quicksort_start. */ | |
115 recvif->s = e+1; | |
116 goto quicksort_start(outif, sp); | |
117 } | |
118 /* recursive call routine end. */ | |
119 | |
120 #define STACK_SIZE 10240 | |
121 | |
122 typedef struct { | |
123 __code (*ret)(void*); | |
124 void *ret_arg; | |
125 stack *sp; | |
126 } QS_FINISH; | |
127 __code | |
128 quicksort(int *v, int s, int e, RET ret, void *arg ) | |
129 { | |
130 framep fp; | |
131 stack sp0, sp; | |
132 sp0 = mustbefreed = malloc(STACK_SIZE); | |
133 sp = sp0 + STACK_SIZE; | |
134 QS_FINISH *finish_if; | |
135 QS_IF *outif; | |
136 | |
137 /* interface for quicksort_finish. */ | |
138 finish_if = (sp -= sizeof(QS_FINISH)); | |
139 finish_if->ret = ret; | |
140 finish_if->ret_arg = arg; | |
141 finish_if->sp = sp0; | |
142 | |
143 /* interface for quicksort_start. */ | |
144 outif = (sp -= sizeof(QS_IF)); | |
145 outif->v = v; | |
146 outif->s = s; | |
147 outif->e = e; | |
148 /* frame for quicksort_finish. */ | |
149 fp = (sp -= sizeof(frame)); | |
150 fp->ret = quicksort_finish; | |
151 fp->interface = finish_if; | |
152 fp->size = sizeof(frame)+sizeof(QS_IF); | |
153 | |
154 goto quicksort_start(outif, sp); | |
155 } | |
156 __code | |
157 quicksort_finish(void *arg, stack sp) | |
158 { | |
159 QS_FINISH interface; | |
160 interface = *(QS_FINISH*)arg; | |
161 //assert((void*)interface.sp==(void*)mustbefreed); | |
162 free(interface.sp); | |
163 goto interface.ret(interface.ret_arg); | |
164 } | |
165 | |
166 | |
167 | |
168 #if 0 | |
169 void | |
170 quicksort_c(int *v, int s0, int e0, stack sp) | |
171 { | |
172 int p; | |
173 int s=s0, e=e0; | |
174 if (e<=s) return; | |
175 | |
176 //p = (v[s]+v[(s+e)/2]+v[e])/3; | |
177 p = mid_point(v[s],v[e],v[(s+e)/2]); | |
178 | |
179 while (1) { | |
180 while (v[s]<p) s++; | |
181 while (p<v[e]) e--; | |
182 | |
183 if (!(s<e)) break; | |
184 SWAP(&v[s], &v[e]); | |
185 s++; e--; | |
186 } | |
187 assert(e+1==s || s==e); | |
188 | |
189 quicksort(v, s0, e); | |
190 quicksort(v, e+1, e0); | |
191 return; | |
192 } | |
193 | |
194 | |
195 | |
196 /* -------------------- | |
197 * | args |fp| | |
198 * -------------------- | |
199 * + ↑ - | |
200 * sp | |
201 */ | |
202 /* ret segmentへgotoしたときのstack spの状態 | |
203 * | |
204 * sp が直接さすのは frame 構造体 | |
205 * frame.size: | |
206 * frame.ret: そのret segmentが終了した時にgotoすべきret segment. | |
207 * frame.interface: frame.retへgotoするときのinterface. | |
208 * このポインタが指すメモリ領域は stack | |
209 * 中にあっても良いしなくても良い。 | |
210 * ただしframe.retを登録した側で解放すべき。 | |
211 * sp+sizeof(frame)が指すのは実行中のret segmentのinterface(引数) | |
212 * これは実行中のret segmentがメモリ管理する | |
213 * 通常はこのret segmentが終了する際に sp+=frame.size とすればよい | |
214 */ | |
215 __code caller0(void *arg, stack sp) | |
216 { | |
217 /* interface for caller_finish0. */ | |
218 double *finish_arg = (sp -= sizeof(double)); | |
219 | |
220 /* arg for quicksort_start. */ | |
221 outif = (sp -= sizeof(*outif)); | |
222 framep fp = (sp -= sizeof(frame)); | |
223 fp->ret = caller_finish; | |
224 fp->interface = NULL; | |
225 fp->size = sizeof(*outif)+sizeof(frame); | |
226 | |
227 goto quicksort_start(outif, sp); | |
228 } | |
229 __code caller_finish0(void *arg, stack sp) | |
230 { | |
231 } | |
232 | |
233 __code __returner0(void *arg , stack sp) | |
234 { | |
235 framep fp = sp; | |
236 sp += fp->size; | |
237 goto fp->ret(fp->interface, sp); | |
238 } | |
239 | |
240 #endif | |
241 | |
242 | |
243 | |
244 |