TempleOSTS_130315.ISO
This commit is contained in:
1 parent
e57428affb
commit
17b71f1a2d
958 files changed
+26043
-15907
No files matched your search
@@ -0,0 +1,194 @@
|
||||
//This uses $LK,"fixed-point","FI:::/TempleOS/Demo/Lectures/FixedPoint.CPP"$.
|
||||
|
||||
#define NUM_CLOUDS 16
|
||||
#define SKY_LINES 30
|
||||
#define CLOUD_PTS 512
|
||||
#define CLOUD_PENS 8
|
||||
#define CLOUD_PEN_PTS 16
|
||||
#define CLOUD_PEN_SIZE 16
|
||||
|
||||
class Cloud
|
||||
{
|
||||
I64 i,x,y,w,h,dx,dy;
|
||||
I64 color;
|
||||
I64 px[CLOUD_PTS],py[CLOUD_PTS],pc[CLOUD_PTS];
|
||||
} clouds[NUM_CLOUDS];
|
||||
|
||||
class CloudPen
|
||||
{
|
||||
CDC *img;
|
||||
I64 px[CLOUD_PEN_PTS],py[CLOUD_PEN_PTS];
|
||||
} cloud_pens[CLOUD_PENS];
|
||||
|
||||
CDC *cloud_pen;
|
||||
|
||||
I64 mp_done_flags;
|
||||
U0 MPDrawClouds(CTask *task)
|
||||
{
|
||||
Cloud *c;
|
||||
CDC *dc=DCAlias(gr_dc,task);
|
||||
I64 i,j,k,xx,yy,
|
||||
lo= Gs->num *CLOUD_PTS/mp_cnt,
|
||||
hi=(Gs->num+1)*CLOUD_PTS/mp_cnt;
|
||||
|
||||
for (j=0,c=clouds;j<NUM_CLOUDS;j++,c++)
|
||||
for (i=lo;i<hi;i++) {
|
||||
k=c->pc[i];
|
||||
if (k<c->color)
|
||||
dc->color=ROP_MONO+LTGRAY;
|
||||
else
|
||||
dc->color=ROP_MONO+WHITE;
|
||||
xx=c->x.i32[1]+c->px[i];
|
||||
yy=c->y.i32[1]+c->py[i];
|
||||
|
||||
k=RandU16&31-16;
|
||||
if (k==-16)
|
||||
k=-c->px[i];
|
||||
c->px[i]+=SignI64(k);
|
||||
|
||||
k=RandU16&31-16;
|
||||
if (k==-16)
|
||||
k=-c->py[i];
|
||||
c->py[i]+=SignI64(k);
|
||||
|
||||
GrBlot(dc,xx,yy,cloud_pens[i&(CLOUD_PENS-1)].img);
|
||||
}
|
||||
DCDel(dc);
|
||||
LBts(&mp_done_flags,Gs->num);
|
||||
}
|
||||
|
||||
U0 DrawIt(CTask *task,CDC *)
|
||||
{
|
||||
I64 i;
|
||||
mp_done_flags=0;
|
||||
for (i=1;i<mp_cnt;i++)
|
||||
MPJob(&MPDrawClouds,task,i);
|
||||
MPDrawClouds(task);
|
||||
while (mp_done_flags!=1<<mp_cnt-1)
|
||||
Yield;
|
||||
}
|
||||
|
||||
U0 AnimateTask(I64)
|
||||
{
|
||||
I64 i,j;
|
||||
Cloud *c;
|
||||
CloudPen *cp;
|
||||
while (TRUE) {
|
||||
WinMgrSync;
|
||||
|
||||
for (i=0,cp=cloud_pens;i<CLOUD_PENS;i++,cp++) {
|
||||
DCClear(cp->img);
|
||||
cp->img->color=COLOR_MONO;
|
||||
for (j=0;j<CLOUD_PEN_PTS;j++) {
|
||||
GrPlot(cp->img,cp->px[j],cp->py[j]);
|
||||
cp->px[j]=LimitI64(cp->px[j]+RandU16%3-1,0,CLOUD_PEN_SIZE-1);
|
||||
cp->py[j]=LimitI64(cp->py[j]+RandU16%3-1,0,CLOUD_PEN_SIZE-1);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0,c=clouds;i<NUM_CLOUDS;i++,c++) {
|
||||
c->x+=c->dx;
|
||||
c->y=LimitI64(c->y+c->dy,0,0.7*(SKY_LINES*FONT_HEIGHT)<<32);
|
||||
c->color=MAX_U16*c->y.i32[1]/(0.8*(SKY_LINES*FONT_HEIGHT));
|
||||
}
|
||||
|
||||
Sleep(20);
|
||||
}
|
||||
}
|
||||
|
||||
#define SAMPLES 6
|
||||
U0 Init()
|
||||
{
|
||||
Cloud *c=clouds;
|
||||
CloudPen *cp=cloud_pens;
|
||||
I64 i,j,k,l,
|
||||
w=Fs->win_pixel_width,
|
||||
h=SKY_LINES*FONT_HEIGHT;
|
||||
|
||||
for (i=0;i<NUM_CLOUDS;i++,c++) {
|
||||
c->x=ToI64(w/2+Rand*w/2-w/4)<<32;
|
||||
c->y=ToI64(h/2+Rand*h/2-h/4)<<32;
|
||||
c->dx=RandI32;
|
||||
c->dy=RandI32;
|
||||
c->w=100;
|
||||
c->h=50;
|
||||
c->color=RandU16;
|
||||
for (l=0;l<CLOUD_PTS;l++) {
|
||||
k=0;
|
||||
for (j=0;j<SAMPLES;j++)
|
||||
k+=RandI16;
|
||||
c->px[l]=(k*c->w/MAX_I16)/SAMPLES;
|
||||
|
||||
k=0;
|
||||
for (j=0;j<SAMPLES;j++)
|
||||
k+=RandI16;
|
||||
c->py[l]=(k*c->h/MAX_I16)/SAMPLES;
|
||||
|
||||
c->pc[l]=RandU16;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0;i<CLOUD_PENS;i++,cp++) {
|
||||
cp->img=DCNew(DCT_COLOR8,CLOUD_PEN_SIZE,CLOUD_PEN_SIZE);
|
||||
for (j=0;j<CLOUD_PEN_PTS;j++) {
|
||||
cp->px[j]=RandU16%CLOUD_PEN_SIZE;
|
||||
cp->py[j]=RandU16%CLOUD_PEN_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 CleanUp()
|
||||
{
|
||||
I64 i;
|
||||
CloudPen *cp=cloud_pens;
|
||||
for (i=0;i<CLOUD_PENS;i++,cp++)
|
||||
DCDel(cp->img);
|
||||
}
|
||||
|
||||
U0 SongTask(I64)
|
||||
{ //Song by the Holy Spirit
|
||||
//This specifies a call-back routine
|
||||
//to be called when the task dies.
|
||||
Fs->task_end_cb=&SndTaskEndCB;
|
||||
MusicSettingsRst;
|
||||
while (TRUE) {
|
||||
Play("W13qBetDA2G3qD2sG!3E2G!3EetCEDqFEeDC");
|
||||
Play("qBetDA2G3qD2sG!3E2G!3EetCEDqFEeDC");
|
||||
Play("C!GqDeADsDCDCqGEetDAD!2sG3D2G!!3D");
|
||||
Play("eC!GqDeADsDCDCqGEetDAD!2sG3D2G!!3D");
|
||||
}
|
||||
}
|
||||
|
||||
U0 CloudScene()
|
||||
{
|
||||
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
|
||||
try {
|
||||
Fs->song_task=Spawn(&SongTask,NULL,"Song",Fs);
|
||||
DocCursor;
|
||||
WinMax;
|
||||
WordStat;
|
||||
Init;
|
||||
Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",Fs);
|
||||
|
||||
"$$CL$$$$BG,LTCYAN$$"; NewLine(SKY_LINES);
|
||||
"$$BG,YELLOW$$";
|
||||
NewLine(5);
|
||||
PutBibleVerse("Exodus,14:19",7);
|
||||
|
||||
Preempt(OFF);
|
||||
Fs->draw_it=&DrawIt;
|
||||
GetChar;
|
||||
WinMgrSync;
|
||||
|
||||
"$$BG$$\n";
|
||||
} catch
|
||||
CatchAll;
|
||||
SettingsPop;
|
||||
CleanUp;
|
||||
}
|
||||
|
||||
//This is so I can use this file stand alone
|
||||
//or as a component of a program.
|
||||
#if IncludeDepth<2
|
||||
CloudScene;
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
interrupt U0 BeepOn()
|
||||
{
|
||||
IntEOI; //signal end of interrupt
|
||||
Snd(100);
|
||||
}
|
||||
|
||||
interrupt U0 BeepOff()
|
||||
{
|
||||
IntEOI;
|
||||
Snd(0);
|
||||
}
|
||||
|
||||
U0 IntTest()
|
||||
{
|
||||
//Modify interrupt descriptor table
|
||||
//for CPU #1.
|
||||
IntEntrySet(I_USER,&BeepOn,IDTET_TRAP);
|
||||
IntEntrySet(I_USER+1,&BeepOff,IDTET_TRAP);
|
||||
MPInt(I_USER,1);
|
||||
Sleep(1000);
|
||||
MPInt(I_USER+1,1);
|
||||
}
|
||||
|
||||
IntTest;
|
||||
Binary file not shown.
@@ -0,0 +1,83 @@
|
||||
class MPCtrl
|
||||
{
|
||||
CTask *win_task;
|
||||
I64 i;
|
||||
Bool app_done,app_done_ack;
|
||||
Bool refresh_start,refresh_done;
|
||||
} mp;
|
||||
|
||||
|
||||
U0 DrawIt(CTask *,CDC *dc)
|
||||
{
|
||||
I64 i;
|
||||
F64 t0=tT,t1;
|
||||
|
||||
mp.refresh_done=FALSE;
|
||||
mp.refresh_start=TRUE;
|
||||
mp.i++;
|
||||
|
||||
for (i=0;i<32;i++) {
|
||||
t1=t0+i*2*ã/64;
|
||||
dc->color=(mp.i+i)/10&15;
|
||||
GrEllipse(dc,GR_WIDTH/2,GR_HEIGHT/2,
|
||||
GR_WIDTH/4*(Sin(t1)+1.0),GR_HEIGHT/4*(Sin(t1)+1.0),t1*2.0);
|
||||
}
|
||||
while (!mp.refresh_done)
|
||||
Yield;
|
||||
}
|
||||
|
||||
U0 MPDrawIt()
|
||||
{
|
||||
I64 i;
|
||||
F64 t0=tT,t1;
|
||||
CDC *dc=DCAlias;
|
||||
dc->win_task=mp.win_task;
|
||||
|
||||
while (!mp.refresh_start && !mp.app_done)
|
||||
Yield;
|
||||
if (mp.app_done)
|
||||
goto mp_done;
|
||||
mp.refresh_start=FALSE;
|
||||
DCFill;
|
||||
for (i=32;i<64;i++) {
|
||||
t1=t0+i*2*ã/64;
|
||||
dc->color=(mp.i+i)/10&15;
|
||||
GrEllipse(dc,GR_WIDTH/2,GR_HEIGHT/2,
|
||||
GR_WIDTH/4*(Sin(t1)+1.0),GR_HEIGHT/4*(Sin(t1)+1.0),t1*2.0);
|
||||
}
|
||||
mp_done:
|
||||
DCDel(dc);
|
||||
mp.refresh_done=TRUE;
|
||||
}
|
||||
|
||||
U0 MPTask(I64)
|
||||
{
|
||||
while (!mp.app_done)
|
||||
MPDrawIt;
|
||||
mp.app_done_ack=TRUE;
|
||||
DCFill;
|
||||
}
|
||||
|
||||
|
||||
U0 LayersSpawn()
|
||||
{
|
||||
if (mp_cnt<2) throw(EXCEPT_MULTICORE);
|
||||
|
||||
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
|
||||
WinMax;
|
||||
DocClear;
|
||||
Fs->draw_it=&DrawIt;
|
||||
WinBorder;
|
||||
|
||||
mp.i=0;
|
||||
mp.app_done=FALSE;
|
||||
mp.win_task=Fs;
|
||||
MPSpawn(&MPTask);
|
||||
GetChar;
|
||||
mp.app_done=TRUE;
|
||||
while (!mp.app_done_ack)
|
||||
Yield;
|
||||
SettingsPop;
|
||||
}
|
||||
|
||||
LayersSpawn;
|
||||
@@ -0,0 +1,57 @@
|
||||
I64 load_test_done;
|
||||
|
||||
U0 Job1(I64)
|
||||
{ //Compile Compiler
|
||||
TaskInitExt; //Enable file access
|
||||
Preempt(ON); //Off by default
|
||||
Silent(ON);
|
||||
while (!load_test_done) {
|
||||
Cd("::/TempleOS/Compiler");
|
||||
Cmp("Compiler");
|
||||
}
|
||||
lock {load_test_done--;}
|
||||
}
|
||||
|
||||
U0 Job2(I64)
|
||||
{ //Log a file
|
||||
TaskInitExt; //Enable file access
|
||||
Preempt(ON); //Off by default
|
||||
while (!load_test_done) {
|
||||
AdamLog("%F","::/TempleOS/Demo/MultiCore/LoadTest.CPP");
|
||||
Yield;
|
||||
}
|
||||
lock {load_test_done--;}
|
||||
}
|
||||
|
||||
U0 Job3(I64)
|
||||
{ //Log a file
|
||||
TaskInitExt; //Enable file access
|
||||
Preempt(ON); //Off by default
|
||||
while (!load_test_done) {
|
||||
Cd("::/TempleOS/Compiler");
|
||||
AdamLog("%F","Compiler.PRJ.Z");
|
||||
Yield;
|
||||
}
|
||||
lock {load_test_done--;}
|
||||
}
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
load_test_done=0;
|
||||
"Running MultiCore Test...\n";
|
||||
MPSpawn(&Job1);
|
||||
MPSpawn(&Job2);
|
||||
MPSpawn(&Job1);
|
||||
MPSpawn(&Job3);
|
||||
Spawn(&Job1);
|
||||
Spawn(&Job2);
|
||||
Spawn(&Job1);
|
||||
Spawn(&Job3);
|
||||
PressAKey;
|
||||
load_test_done=8;
|
||||
//We don't want to yank code from under MP cores.
|
||||
while (load_test_done)
|
||||
Yield;
|
||||
}
|
||||
|
||||
Main;
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
lock{} is a compiler statement
|
||||
which places asm LOCK instruction
|
||||
prefixes on code. Only use it on
|
||||
read-modify-write statements.
|
||||
It will generate invalid instructions
|
||||
if you misuse it and it will crash.
|
||||
$LK,"U","MN:U"$() to see what code was generated.
|
||||
*/
|
||||
|
||||
#define CNT 0x1000000
|
||||
|
||||
I64 glbl;
|
||||
|
||||
|
||||
U0 MPUnlockedInc(I64)
|
||||
{
|
||||
I64 i;
|
||||
for (i=0;i<CNT;i++)
|
||||
glbl++;
|
||||
}
|
||||
|
||||
U0 UnlockedInc()
|
||||
{
|
||||
I64 i;
|
||||
CMPCmd *tempm;
|
||||
glbl=0;
|
||||
|
||||
tempm=MPJob(&MPUnlockedInc,NULL,1,0);
|
||||
for (i=0;i<CNT;i++)
|
||||
glbl++;
|
||||
|
||||
MPJobResult(tempm);
|
||||
"Correct Cnt:%X Actual Cnt:%X\n",CNT*2,glbl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
U0 MPLockedInc(I64)
|
||||
{
|
||||
I64 i;
|
||||
for (i=0;i<CNT;i++)
|
||||
lock //Can be used without {}
|
||||
glbl++;
|
||||
}
|
||||
|
||||
U0 LockedInc()
|
||||
{
|
||||
I64 i;
|
||||
CMPCmd *tempm;
|
||||
glbl=0;
|
||||
|
||||
tempm=MPJob(&MPLockedInc,NULL,1,0);
|
||||
for (i=0;i<CNT;i++)
|
||||
lock {
|
||||
glbl++;
|
||||
}
|
||||
|
||||
MPJobResult(tempm);
|
||||
"Correct Cnt:%X Actual Cnt:%X\n",CNT*2,glbl;
|
||||
}
|
||||
|
||||
UnlockedInc;
|
||||
LockedInc;
|
||||
@@ -0,0 +1,85 @@
|
||||
I64 mp_n;
|
||||
|
||||
I64 MPSum(I64 my_mp_cnt)
|
||||
{ //We could use the formula n*(n+1)/2
|
||||
I64 lo=mp_n*Gs->num/my_mp_cnt,
|
||||
hi=mp_n*(Gs->num+1)/my_mp_cnt,
|
||||
result=0,i;
|
||||
for (i=lo;i<hi;i++)
|
||||
result+=i;
|
||||
return result;
|
||||
}
|
||||
|
||||
I64 Sum(I64 n,I64 my_mp_cnt)
|
||||
{
|
||||
CMPCmd *tempm[MP_MAX_PROCESSORS];
|
||||
I64 result=0,i;
|
||||
mp_n=n+1;
|
||||
for (i=1;i<my_mp_cnt;i++)
|
||||
tempm[i]=MPJob(&MPSum,my_mp_cnt,i,0);
|
||||
result=MPSum(my_mp_cnt);
|
||||
for (i=1;i<my_mp_cnt;i++)
|
||||
result+=MPJobResult(tempm[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#define SAMPLE_SIZE 100
|
||||
|
||||
F64 Test(I64 n,I64 my_mp_cnt)
|
||||
{
|
||||
I64 i,val=0;
|
||||
F64 start,end;
|
||||
start=tT;
|
||||
for (i=0;i<SAMPLE_SIZE;i++)
|
||||
val+=Sum(n,my_mp_cnt);
|
||||
end=tT;
|
||||
"Val:%,d\n",val/SAMPLE_SIZE;
|
||||
"$$FG,RED$$N:%12,d Time:%10.8f$$FG$$\n",n,(end-start)/SAMPLE_SIZE;
|
||||
return end-start;
|
||||
}
|
||||
|
||||
#define NUM_TESTS 7
|
||||
#define MAX_PERCENT 200
|
||||
|
||||
U0 MPAdd()
|
||||
{
|
||||
I64 i,n,
|
||||
h=Fs->win_pixel_width,
|
||||
v=Fs->win_pixel_height;
|
||||
F64 t1,t2,results[NUM_TESTS];
|
||||
CDC *dc=DCAlias;
|
||||
|
||||
for (i=0,n=10;i<NUM_TESTS;i++,n*=10) {
|
||||
t1=Test(n,1);
|
||||
t2=Test(n,mp_cnt);
|
||||
results[i]=t2*100.0/t1;
|
||||
"$$FG,GREEN$$%8.4f%%$$FG$$\n\n",results[i];
|
||||
}
|
||||
PressAKey;
|
||||
|
||||
DocClear;
|
||||
|
||||
dc->color=BLUE;
|
||||
for (i=0;i<MAX_PERCENT;i+=MAX_PERCENT/10) {
|
||||
GrPrintF(dc,0,v-ToF64(i)/MAX_PERCENT*v-FONT_HEIGHT,"%3d%%",i);
|
||||
GrLine(dc,0,v-ToF64(i)/MAX_PERCENT*v,h,v-ToF64(i)/MAX_PERCENT*v);
|
||||
}
|
||||
|
||||
for (i=0;i<NUM_TESTS-1;i++) {
|
||||
dc->color=RED;
|
||||
dc->pen_width=2;
|
||||
GrLine3(dc,i*h/(NUM_TESTS-1), v-results[i ]/MAX_PERCENT*v,0,
|
||||
(i+1)*h/(NUM_TESTS-1),v-results[i+1]/MAX_PERCENT*v,0);
|
||||
dc->color=GREEN;
|
||||
GrPrintF(dc,i*h/(NUM_TESTS-1),v-FONT_HEIGHT,"10e%d",i+1);
|
||||
GrLine(dc,i*h/(NUM_TESTS-1),0,
|
||||
i*h/(NUM_TESTS-1),v);
|
||||
}
|
||||
PressAKey;
|
||||
|
||||
DCFill;
|
||||
DCDel(dc);
|
||||
}
|
||||
|
||||
MPAdd;
|
||||
@@ -0,0 +1,18 @@
|
||||
U0 Job(CDoc *doc)
|
||||
{
|
||||
I64 i;
|
||||
for (i=0;i<10;i++)
|
||||
DocPrintF(doc,"$$FG,%d$$CPU%d ",Gs->num,Gs->num);
|
||||
}
|
||||
|
||||
|
||||
U0 MPPrintFDemo()
|
||||
{
|
||||
I64 i;
|
||||
for (i=0;i<1000;i++)
|
||||
MPJob(&Job,DocCur,1+i%(mp_cnt-1));
|
||||
Sleep(1000);
|
||||
"$$FG$$\n";
|
||||
}
|
||||
|
||||
MPPrintFDemo;
|
||||
@@ -0,0 +1,63 @@
|
||||
Bool noise_done;
|
||||
I64 done_ack;
|
||||
I64 cnt;
|
||||
|
||||
U0 DrawNoise(CTask *task)
|
||||
{
|
||||
I64 i,
|
||||
h=task->win_pixel_width,
|
||||
v=task->win_pixel_height;
|
||||
CDC *dc=DCAlias(gr_dc2,task);
|
||||
for (i=0;i<cnt;i++) {
|
||||
dc->color=RandU16&15;
|
||||
GrPlot(dc,RandU16%h,RandU16%v);
|
||||
}
|
||||
dc->color=WHITE;
|
||||
GrRect(dc,0,Gs->num*FONT_HEIGHT,12*FONT_WIDTH,FONT_HEIGHT);
|
||||
dc->color=BLACK;
|
||||
GrPrintF(dc,0,Gs->num*FONT_HEIGHT,"Cnt:%08X",cnt);
|
||||
DCDel(dc);
|
||||
}
|
||||
|
||||
U0 MPTask(CTask *task)
|
||||
{
|
||||
while (!noise_done) {
|
||||
DrawNoise(task);
|
||||
WinMgrSync;
|
||||
}
|
||||
LBts(&done_ack,Gs->num);
|
||||
}
|
||||
|
||||
U0 NoiseDemo()
|
||||
{
|
||||
I64 i;
|
||||
F64 t0;
|
||||
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
|
||||
WinMax;
|
||||
WordStat;
|
||||
cnt=0x1000;
|
||||
|
||||
noise_done=FALSE;
|
||||
for (i=1;i<mp_cnt;i++)
|
||||
MPSpawn(&MPTask,Fs,"Job",i);
|
||||
|
||||
while (!ScanChar) {
|
||||
t0=tT;
|
||||
DrawNoise(Fs);
|
||||
if (tT-t0>1.0/80.0)
|
||||
cnt-=0x100;
|
||||
else
|
||||
cnt+=0x100;
|
||||
WinMgrSync;
|
||||
}
|
||||
|
||||
done_ack=1;
|
||||
noise_done=TRUE;
|
||||
while (done_ack!=1<<mp_cnt-1)
|
||||
Yield;
|
||||
|
||||
DCFill;
|
||||
SettingsPop;
|
||||
}
|
||||
|
||||
NoiseDemo;
|
||||
@@ -0,0 +1,98 @@
|
||||
#define BORDER_CHARS 1
|
||||
|
||||
U8 *buf;
|
||||
I64 size,mp_done_flags;
|
||||
CDoc *doc;
|
||||
|
||||
U0 PDNormalize()
|
||||
{
|
||||
U8 *r=MAlloc(size+2*BORDER_CHARS),
|
||||
*src=buf,*dst=r;
|
||||
I64 ch;
|
||||
*dst++='['; //Border
|
||||
while (size--) {
|
||||
ch=*src++;
|
||||
if ('a'<=ch<='z') //lower is most common so do first
|
||||
*dst++=ch;
|
||||
else if ('A'<=ch<='Z')
|
||||
*dst++=ch+'a'-'A'; //Convert to lower
|
||||
}
|
||||
*dst++=']'; //Border
|
||||
Free(buf);
|
||||
buf=r;
|
||||
size=dst-r-2*BORDER_CHARS;
|
||||
}
|
||||
|
||||
|
||||
U0 PDAnswer(U8 *a,I64 len)
|
||||
{
|
||||
DocLock(doc);
|
||||
a-=(len-1)/2;
|
||||
DocPrintF(doc,"CPU:%d Len:%2d ",Gs->num,len);
|
||||
while (len--)
|
||||
DocPrintF(doc,"%C",*a++); //%C is toupper char
|
||||
DocPutS(doc,"\n");
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
U0 MPPalindrome(I64 dummy=0)
|
||||
{
|
||||
nounusedwarn dummy;
|
||||
U8 *src=buf+BORDER_CHARS+size*Gs->num/mp_cnt,
|
||||
*f,*b;
|
||||
I64 len,best=0,
|
||||
my_size=(size+mp_cnt-1)/mp_cnt;
|
||||
while (my_size--) {
|
||||
|
||||
//Odd
|
||||
f=src+1;
|
||||
b=src-1;
|
||||
while (*f==*b) {
|
||||
f++;
|
||||
b--;
|
||||
}
|
||||
len=f-b+1-2;
|
||||
if (len>best) {
|
||||
best=len;
|
||||
PDAnswer(src,len);
|
||||
}
|
||||
|
||||
//Even
|
||||
f=src+1;
|
||||
b=src;
|
||||
while (*f==*b) {
|
||||
f++;
|
||||
b--;
|
||||
}
|
||||
len=f-b+1-2;
|
||||
if (len>best) {
|
||||
best=len;
|
||||
PDAnswer(src,len);
|
||||
}
|
||||
|
||||
src++;
|
||||
}
|
||||
LBts(&mp_done_flags,Gs->num);
|
||||
}
|
||||
|
||||
U0 Palindrome(U8 *filename)
|
||||
{
|
||||
I64 i;
|
||||
F64 t0=tT;
|
||||
|
||||
buf=FileRead(filename,&size);
|
||||
PDNormalize;
|
||||
|
||||
doc=DocCur;
|
||||
mp_done_flags=0;
|
||||
for (i=1;i<mp_cnt;i++)
|
||||
MPJob(&MPPalindrome,NULL,i);
|
||||
MPPalindrome;
|
||||
while (mp_done_flags!=1<<mp_cnt-1)
|
||||
Yield;
|
||||
|
||||
Free(buf);
|
||||
"Time:%9.5f\n",tT-t0;
|
||||
}
|
||||
|
||||
Palindrome(Define("ST_BIBLE_FILE"));
|
||||
@@ -0,0 +1,76 @@
|
||||
U8 *master_bitmap;
|
||||
I64 prime_range,my_mp_cnt,pending;
|
||||
|
||||
U0 PrimesJob(I64 i)
|
||||
{
|
||||
I64 j,k,l=Sqrt(prime_range),
|
||||
lo=i*prime_range/my_mp_cnt,
|
||||
hi=(i+1)*prime_range/my_mp_cnt,
|
||||
lo2=lo+sys_cache_line_width,
|
||||
hi2=hi-sys_cache_line_width;
|
||||
if (lo2>hi2) lo2=hi2;
|
||||
for (j=2;j<=l;j++) {
|
||||
if (!Bt(master_bitmap,j)) {
|
||||
if (j>=lo)
|
||||
k=j+j;
|
||||
else {
|
||||
k=lo-lo%j;
|
||||
if (k<lo)
|
||||
k+=j;
|
||||
}
|
||||
while (k<lo2) {
|
||||
LBts(master_bitmap,k);
|
||||
k+=j;
|
||||
}
|
||||
while (k<hi2) {
|
||||
Bts(master_bitmap,k);
|
||||
k+=j;
|
||||
}
|
||||
while (k<hi) {
|
||||
LBts(master_bitmap,k);
|
||||
k+=j;
|
||||
}
|
||||
}
|
||||
}
|
||||
lock pending--;
|
||||
}
|
||||
|
||||
I64 Primes(I64 range,I64 _my_mp_cnt)
|
||||
{
|
||||
I64 i,prime_cnt=0;
|
||||
F64 t0=tT,tf;
|
||||
prime_range=range;
|
||||
if (_my_mp_cnt<=mp_cnt)
|
||||
my_mp_cnt=_my_mp_cnt;
|
||||
else
|
||||
my_mp_cnt=mp_cnt;
|
||||
master_bitmap=CAlloc((prime_range+7)/8+1);
|
||||
Bts(master_bitmap,0);
|
||||
Bts(master_bitmap,1);
|
||||
pending=my_mp_cnt;
|
||||
for (i=1;i<my_mp_cnt;i++)
|
||||
MPJob(&PrimesJob,i,i);
|
||||
PrimesJob(0);
|
||||
while (pending)
|
||||
Yield;
|
||||
tf=tT;
|
||||
|
||||
for (i=0;i<prime_range;i++)
|
||||
if (!Bt(master_bitmap,i))
|
||||
prime_cnt++;
|
||||
|
||||
for (i=MaxI64(prime_range-100,0);i<prime_range;i++)
|
||||
if (!Bt(master_bitmap,i))
|
||||
"%d ",i;
|
||||
|
||||
"\n$$FG,RED$$CPUs:%d PrimeRange:%,d PrimeCnt:%,d Time:%9.6,f$$FG$$\n",
|
||||
my_mp_cnt,prime_range,prime_cnt,tf-t0;
|
||||
|
||||
Free(master_bitmap);
|
||||
return prime_cnt;
|
||||
}
|
||||
|
||||
Primes(100,1);
|
||||
Primes(100,mp_cnt);
|
||||
Primes(1000000,1);
|
||||
Primes(1000000,mp_cnt);
|
||||
@@ -0,0 +1,165 @@
|
||||
#define NUM 1000000
|
||||
|
||||
I64 my_mp_cnt=1<<Bsr(mp_cnt);//Power of 2
|
||||
|
||||
I32 *a1,*a2;
|
||||
I32 *b[my_mp_cnt],bn[my_mp_cnt];
|
||||
I64 mp_done_flags;
|
||||
|
||||
I64 Compare(I32 *e1,I32 *e2)
|
||||
{
|
||||
return *e1-*e2;
|
||||
}
|
||||
|
||||
|
||||
U0 QSortU32(I32 *base,I64 num)
|
||||
{
|
||||
// By customizing, we dramatically improve it!
|
||||
// Cut and paste from $LK,"QSortI64","MN:QSortI64"$().
|
||||
I64 i;
|
||||
I32 *less,*greater,pivot;
|
||||
if (num>1) {
|
||||
do {
|
||||
less=base;
|
||||
greater=base+num;
|
||||
pivot=base[num/2];
|
||||
while (less<greater) {
|
||||
if (*less<=pivot)
|
||||
less++;
|
||||
else {
|
||||
greater--;
|
||||
SwapU32(less,greater);
|
||||
}
|
||||
}
|
||||
i=less-base;
|
||||
if (i==num) { //All less or equal to pivot
|
||||
|
||||
//Point greater to first less
|
||||
do greater--;
|
||||
while (--i && *greater==pivot);
|
||||
|
||||
if (i) {
|
||||
less=base+num/2; //Pivot was not moved, point to it
|
||||
if (less<greater)
|
||||
SwapU32(less,greater);
|
||||
num=i;
|
||||
} else //All equal
|
||||
break;
|
||||
} else if (i<num/2) {
|
||||
QSortU32(base,i);
|
||||
num-=i;
|
||||
base=greater;
|
||||
} else {
|
||||
QSortU32(greater,num-i);
|
||||
num=i;
|
||||
}
|
||||
} while (num>1);
|
||||
}
|
||||
}
|
||||
|
||||
U0 MPSort(I64 dummy=0)
|
||||
{
|
||||
nounusedwarn dummy;
|
||||
QSortU32(b[Gs->num],bn[Gs->num]);
|
||||
LBts(&mp_done_flags,Gs->num);
|
||||
}
|
||||
|
||||
U0 MPRadixSortDemo(I64 dummy=0)
|
||||
{
|
||||
nounusedwarn dummy;
|
||||
I64 i,j,k1,k2;
|
||||
F64 t0;
|
||||
a1=MAlloc(NUM*sizeof(I32));
|
||||
for (i=0;i<NUM;i++)
|
||||
a1[i]=RandI32;
|
||||
|
||||
|
||||
a2=MAlloc(NUM*sizeof(I32));
|
||||
|
||||
"$$FG,GREEN$$QSort$$FG$$\n";
|
||||
t0=tT;
|
||||
MemCpy(a2,a1,sizeof(I32)*NUM);
|
||||
QSort(a2,NUM,sizeof(I32),&Compare);
|
||||
"Time:%9.6f\n",tT-t0;
|
||||
D(a2+NUM/4);
|
||||
|
||||
|
||||
"$$FG,GREEN$$QSortU32$$FG$$\n";
|
||||
t0=tT;
|
||||
MemCpy(a2,a1,sizeof(I32)*NUM);
|
||||
QSortU32(a2,NUM);
|
||||
"Time:%9.6f\n",tT-t0;
|
||||
D(a2+NUM/4);
|
||||
|
||||
for (i=0;i<my_mp_cnt;i++) {
|
||||
//$WW,0$We must do full size, just in case.
|
||||
//There will be uneven split between cores
|
||||
//depending on the distribution of rand numbers.
|
||||
b[i]=MAlloc(NUM*sizeof(I32));
|
||||
bn[i]=0;
|
||||
}
|
||||
|
||||
if (my_mp_cnt<2) throw(EXCEPT_MULTICORE);
|
||||
|
||||
"$$FG,GREEN$$MP Radix QSortU32$$FG$$\n";
|
||||
t0=tT;
|
||||
k1=32-Bsr(my_mp_cnt);
|
||||
k2=my_mp_cnt/2;
|
||||
for (i=0;i<NUM;i++) {
|
||||
j=a1[i]>>k1+k2; //This is a preliminary radix sort.
|
||||
b[j][bn[j]++]=a1[i];
|
||||
}
|
||||
mp_done_flags=0;
|
||||
for (i=1;i<my_mp_cnt;i++)
|
||||
MPSpawn(&MPSort,NULL,NULL,i);
|
||||
MPSort;
|
||||
while (mp_done_flags!=1<<my_mp_cnt-1)
|
||||
Yield;
|
||||
j=0;
|
||||
for (i=0;i<my_mp_cnt;i++) {
|
||||
MemCpy(&a2[j],b[i],bn[i]*sizeof(I32));
|
||||
j+=bn[i];
|
||||
}
|
||||
"Time:%9.6f\n",tT-t0;
|
||||
D(a2+NUM/4);
|
||||
|
||||
Free(a1);
|
||||
Free(a2);
|
||||
for (i=0;i<my_mp_cnt;i++)
|
||||
Free(b[i]);
|
||||
}
|
||||
|
||||
MPRadixSortDemo;
|
||||
|
||||
/*$HL,0$ Results on $FG$$BG$8 Cores 2.660GHz Core i7:
|
||||
$FG$$BG$$FG,2$QSort$FG$
|
||||
Time: 1.535474
|
||||
00000000 EA 1D F6 BF 16 2E F6 BF 0B 3C F6 BF CD 44 F6 BF ê.ö¿..ö¿.<ö¿ÍDö¿
|
||||
00000010 B1 45 F6 BF 52 4A F6 BF 96 71 F6 BF 9F 78 F6 BF ±Eö¿RJö¿–qö¿Ÿxö¿
|
||||
00000020 52 87 F6 BF 23 9F F6 BF EF AD F6 BF 2D B4 F6 BF R‡ö¿#Ÿö¿ïö¿-´ö¿
|
||||
00000030 4B EE F6 BF 60 FA F6 BF 31 08 F7 BF 1A 0E F7 BF Kîö¿`úö¿1.÷¿..÷¿
|
||||
00000040 5C 39 F7 BF 26 3B F7 BF C7 3D F7 BF CF 3D F7 BF \9÷¿&;÷¿Ç=÷¿Ï=÷¿
|
||||
00000050 7D 51 F7 BF 2F 79 F7 BF 7B 7A F7 BF CF 8C F7 BF }Q÷¿/y÷¿{z÷¿ÏŒ÷¿
|
||||
00000060 09 95 F7 BF 04 A3 F7 BF D2 A8 F7 BF 61 EA F7 BF .•÷¿.£÷¿Ò¨÷¿aê÷¿
|
||||
00000070 2D ED F7 BF F2 03 F8 BF 4C 09 F8 BF BB 09 F8 BF -í÷¿ò.ø¿L.ø¿».ø¿
|
||||
$FG,2$QSortU32$FG$
|
||||
Time: 0.132599
|
||||
00000000 EA 1D F6 BF 16 2E F6 BF 0B 3C F6 BF CD 44 F6 BF ê.ö¿..ö¿.<ö¿ÍDö¿
|
||||
00000010 B1 45 F6 BF 52 4A F6 BF 96 71 F6 BF 9F 78 F6 BF ±Eö¿RJö¿–qö¿Ÿxö¿
|
||||
00000020 52 87 F6 BF 23 9F F6 BF EF AD F6 BF 2D B4 F6 BF R‡ö¿#Ÿö¿ïö¿-´ö¿
|
||||
00000030 4B EE F6 BF 60 FA F6 BF 31 08 F7 BF 1A 0E F7 BF Kîö¿`úö¿1.÷¿..÷¿
|
||||
00000040 5C 39 F7 BF 26 3B F7 BF C7 3D F7 BF CF 3D F7 BF \9÷¿&;÷¿Ç=÷¿Ï=÷¿
|
||||
00000050 7D 51 F7 BF 2F 79 F7 BF 7B 7A F7 BF CF 8C F7 BF }Q÷¿/y÷¿{z÷¿ÏŒ÷¿
|
||||
00000060 09 95 F7 BF 04 A3 F7 BF D2 A8 F7 BF 61 EA F7 BF .•÷¿.£÷¿Ò¨÷¿aê÷¿
|
||||
00000070 2D ED F7 BF F2 03 F8 BF 4C 09 F8 BF BB 09 F8 BF -í÷¿ò.ø¿L.ø¿».ø¿
|
||||
$FG,2$MP Radix QSortU32$FG$
|
||||
Time: 0.024471
|
||||
00000000 EA 1D F6 BF 16 2E F6 BF 0B 3C F6 BF CD 44 F6 BF ê.ö¿..ö¿.<ö¿ÍDö¿
|
||||
00000010 B1 45 F6 BF 52 4A F6 BF 96 71 F6 BF 9F 78 F6 BF ±Eö¿RJö¿–qö¿Ÿxö¿
|
||||
00000020 52 87 F6 BF 23 9F F6 BF EF AD F6 BF 2D B4 F6 BF R‡ö¿#Ÿö¿ïö¿-´ö¿
|
||||
00000030 4B EE F6 BF 60 FA F6 BF 31 08 F7 BF 1A 0E F7 BF Kîö¿`úö¿1.÷¿..÷¿
|
||||
00000040 5C 39 F7 BF 26 3B F7 BF C7 3D F7 BF CF 3D F7 BF \9÷¿&;÷¿Ç=÷¿Ï=÷¿
|
||||
00000050 7D 51 F7 BF 2F 79 F7 BF 7B 7A F7 BF CF 8C F7 BF }Q÷¿/y÷¿{z÷¿ÏŒ÷¿
|
||||
00000060 09 95 F7 BF 04 A3 F7 BF D2 A8 F7 BF 61 EA F7 BF .•÷¿.£÷¿Ò¨÷¿aê÷¿
|
||||
00000070 2D ED F7 BF F2 03 F8 BF 4C 09 F8 BF BB 09 F8 BF -í÷¿ò.ø¿L.ø¿».ø¿
|
||||
$HL,1$*/
|
||||
@@ -0,0 +1,113 @@
|
||||
class MPCtrl
|
||||
{
|
||||
Bool done[MP_MAX_PROCESSORS];
|
||||
} mp;
|
||||
|
||||
I32 *a1=NULL, //This is the master copy of random nums
|
||||
//so we have the same nums for both tests.
|
||||
*a2=NULL, //This is the temp copy.
|
||||
*a3=NULL; //This is a merged final array for dual core example.
|
||||
|
||||
U0 Init(I64 n)
|
||||
{
|
||||
I64 i;
|
||||
Free(a1);
|
||||
a1=MAlloc(n*sizeof(I32));
|
||||
for (i=0;i<n;i++)
|
||||
a1[i]=RandI32;
|
||||
Free(a2);
|
||||
a2=MAlloc(n*sizeof(I32));
|
||||
Free(a3);
|
||||
a3=MAlloc(n*sizeof(I32));
|
||||
}
|
||||
|
||||
U0 CleanUp()
|
||||
{
|
||||
Free(a1);
|
||||
a1=NULL;
|
||||
Free(a2);
|
||||
a2=NULL;
|
||||
Free(a3);
|
||||
a3=NULL;
|
||||
}
|
||||
|
||||
U0 Output(I32 *a,I64 n)
|
||||
{
|
||||
I64 i;
|
||||
WinMax;
|
||||
for (i=0;i<n;i++) {
|
||||
"%08X ",a[i];
|
||||
if (i&7==3)
|
||||
NewLine;
|
||||
}
|
||||
NewLine;
|
||||
}
|
||||
|
||||
I64 IntCompare(I32 *i1,I32 *i2)
|
||||
{
|
||||
return *i1-*i2;
|
||||
}
|
||||
|
||||
F64 Sort1(I64 n)
|
||||
{
|
||||
F64 t0=tT;
|
||||
MemCpy(a2,a1,n*sizeof(I32));
|
||||
QSort(a2,n,sizeof(I32),&IntCompare);
|
||||
mp.done[Gs->num]=TRUE;
|
||||
return tT-t0;
|
||||
}
|
||||
|
||||
F64 Sort2(I64 n)
|
||||
{
|
||||
I64 i1=0,i2=n/2,i3=0;
|
||||
F64 t0=tT;
|
||||
MemSet(&mp,0,sizeof(MPCtrl));
|
||||
MemCpy(&a2[n/2],&a1[n/2],n/2*sizeof(I32));
|
||||
MPJob(&Sort1,n/2,1);
|
||||
QSort(&a2[n/2],n/2,sizeof(I32),&IntCompare);
|
||||
while (!mp.done[1])
|
||||
Yield;
|
||||
while (i3<n) {
|
||||
if (i2==n)
|
||||
while (i3<n)
|
||||
a3[i3++]=a2[i1++];
|
||||
else
|
||||
while (i3<n && i1<n/2 && a2[i1]<=a2[i2])
|
||||
a3[i3++]=a2[i1++];
|
||||
if (i1==n/2)
|
||||
while (i3<n)
|
||||
a3[i3++]=a2[i2++];
|
||||
else
|
||||
while (i3<n && i2<n && a2[i2]<=a2[i1])
|
||||
a3[i3++]=a2[i2++];
|
||||
}
|
||||
return tT-t0;
|
||||
}
|
||||
|
||||
#define SAMPLES 8
|
||||
|
||||
U0 CompareSorts(I64 n)
|
||||
{
|
||||
I64 i;
|
||||
F64 t1=0,t2=0;
|
||||
for (i=0;i<SAMPLES;i++) {
|
||||
//The times depend heavily on the random num arrays
|
||||
//so run multiple times, to get an average.
|
||||
Init(n);
|
||||
|
||||
t1+=Sort1(n);
|
||||
// Output(a2,n);
|
||||
|
||||
t2+=Sort2(n);
|
||||
// Output(a3,n);
|
||||
}
|
||||
CleanUp;
|
||||
"Array N:%08X Timings Sampled:%d\n",n,SAMPLES;
|
||||
"Single Core Average Time:%9.5fs\n",t1/SAMPLES;
|
||||
"Dual Core Average Time :%9.5fs\n",t2/SAMPLES;
|
||||
NewLine;
|
||||
}
|
||||
|
||||
CompareSorts(0x4000);
|
||||
CompareSorts(0x8000);
|
||||
CompareSorts(0x10000);
|
||||
Reference in new issue
Block a user