Initial (manual) import
This commit is contained in:
1 parent
f39611c506
commit
895fe109de
661 files changed
+245862
No files matched your search
@@ -0,0 +1,23 @@
|
||||
interrupt U0 IntBeepOn()
|
||||
{
|
||||
*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0; //signal end of interrupt
|
||||
Snd(34);
|
||||
}
|
||||
|
||||
interrupt U0 IntBeepOff()
|
||||
{
|
||||
*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
|
||||
Snd;
|
||||
}
|
||||
|
||||
U0 IntTest()
|
||||
{//Modify interrupt descriptor table use by all cores.
|
||||
IntEntrySet(I_USER,&IntBeepOn,IDTET_TRAP);
|
||||
IntEntrySet(I_USER+1,&IntBeepOff,IDTET_TRAP);
|
||||
//Issue interupt to core1
|
||||
MPInt(I_USER,1);
|
||||
Sleep(1000);
|
||||
MPInt(I_USER+1,1);
|
||||
}
|
||||
|
||||
IntTest;
|
||||
@@ -0,0 +1,48 @@
|
||||
Bool app_done;
|
||||
I64 app_done_ack;
|
||||
|
||||
U0 Job1(I64)
|
||||
{//Compile Compiler
|
||||
Silent;
|
||||
while (!app_done) {
|
||||
Cd("::/Compiler");
|
||||
Cmp("Compiler");
|
||||
}
|
||||
lock {app_done_ack--;}
|
||||
}
|
||||
|
||||
U0 Job2(I64)
|
||||
{//Log a file
|
||||
while (!app_done) {
|
||||
AdamLog("%F","::/Demo/MultiCore/LoadTest.HC");
|
||||
Yield;
|
||||
}
|
||||
lock {app_done_ack--;}
|
||||
}
|
||||
|
||||
U0 Job3(I64)
|
||||
{//Log a file
|
||||
while (!app_done) {
|
||||
Cd("::/Compiler");
|
||||
AdamLog("%F","Compiler.PRJ.Z");
|
||||
Yield;
|
||||
}
|
||||
lock {app_done_ack--;}
|
||||
}
|
||||
|
||||
U0 Main()
|
||||
{
|
||||
app_done=FALSE;
|
||||
"Running MultiCore Test...\n";
|
||||
Spawn(&Job1,,,1); //core #1
|
||||
Spawn(&Job2,,,1);
|
||||
Spawn(&Job3,,,1);
|
||||
PressAKey;
|
||||
//We don't want to yank code from under MP cores.
|
||||
app_done_ack=3;
|
||||
app_done=TRUE;
|
||||
while (app_done_ack)
|
||||
Yield;
|
||||
}
|
||||
|
||||
Main;
|
||||
@@ -0,0 +1,52 @@
|
||||
/*lock{} is a compiler stmt
|
||||
which places asm LOCK inst
|
||||
prefixes on code. Only use it on
|
||||
read-modify-write stmts.
|
||||
It will generate invalid insts
|
||||
if you misuse it and it will crash.
|
||||
$LK,"U",A="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()
|
||||
{
|
||||
CJob *tmpm0,*tmpm1;
|
||||
glbl=0;
|
||||
tmpm0=JobQue(&MPUnlockedInc,NULL,0,0);
|
||||
tmpm1=JobQue(&MPUnlockedInc,NULL,1,0);
|
||||
JobResGet(tmpm0);
|
||||
JobResGet(tmpm1);
|
||||
"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()
|
||||
{
|
||||
CJob *tmpm0,*tmpm1;
|
||||
glbl=0;
|
||||
tmpm0=JobQue(&MPLockedInc,NULL,0,0);
|
||||
tmpm1=JobQue(&MPLockedInc,NULL,1,0);
|
||||
JobResGet(tmpm0);
|
||||
JobResGet(tmpm1);
|
||||
"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,
|
||||
res=0,i;
|
||||
for (i=lo;i<hi;i++)
|
||||
res+=i;
|
||||
return res;
|
||||
}
|
||||
|
||||
I64 Sum(I64 n,I64 my_mp_cnt)
|
||||
{
|
||||
CJob *tmpm[MP_PROCESSORS_NUM];
|
||||
I64 res=0,i;
|
||||
mp_n=n+1;
|
||||
for (i=0;i<my_mp_cnt;i++)
|
||||
tmpm[i]=JobQue(&MPSum,my_mp_cnt,i,0);
|
||||
for (i=0;i<my_mp_cnt;i++)
|
||||
res+=JobResGet(tmpm[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
#define SAMPLE_SIZE 100
|
||||
|
||||
F64 Test(I64 n,I64 my_mp_cnt)
|
||||
{
|
||||
I64 i,val=0;
|
||||
F64 start,end;
|
||||
start=tS;
|
||||
for (i=0;i<SAMPLE_SIZE;i++)
|
||||
val+=Sum(n,my_mp_cnt);
|
||||
end=tS;
|
||||
"Val:%,d\n",val/SAMPLE_SIZE;
|
||||
"$$RED$$N:%12,d Time:%10.8f$$FG$$\n",n,(end-start)/SAMPLE_SIZE;
|
||||
return end-start;
|
||||
}
|
||||
|
||||
#define VAL_MIN 1000
|
||||
#define TEST_MIN 3
|
||||
#define TEST_MAX 7
|
||||
#define TESTS_NUM (TEST_MAX-TEST_MIN+1)
|
||||
#define PERCENT_MAX 200
|
||||
|
||||
U0 MPAdd()
|
||||
{
|
||||
I64 i,n,
|
||||
h=Fs->pix_width,
|
||||
v=Fs->pix_height;
|
||||
F64 t1,t2,ress[TESTS_NUM];
|
||||
CDC *dc=DCAlias;
|
||||
|
||||
for (i=0,n=VAL_MIN;i<TESTS_NUM;i++,n*=10) {
|
||||
t1=Test(n,1);
|
||||
t2=Test(n,mp_cnt);
|
||||
ress[i]=t2*100.0/t1;
|
||||
"$$GREEN$$%8.4f%%$$FG$$\n\n",ress[i];
|
||||
}
|
||||
PressAKey;
|
||||
|
||||
DocClear;
|
||||
|
||||
dc->color=BLUE;
|
||||
for (i=PERCENT_MAX/10;i<PERCENT_MAX;i+=PERCENT_MAX/10) {
|
||||
GrPrint(dc,0,v-ToF64(i)/PERCENT_MAX*v-FONT_HEIGHT,"%3d%%",i);
|
||||
GrLine(dc,0,v-ToF64(i)/PERCENT_MAX*v,h,v-ToF64(i)/PERCENT_MAX*v);
|
||||
}
|
||||
|
||||
for (i=0;i<TESTS_NUM-1;i++) {
|
||||
dc->color=RED;
|
||||
dc->pen_width=2;
|
||||
GrLine3(dc,i*h/(TESTS_NUM-1), v-ress[i ]/PERCENT_MAX*v,0,
|
||||
(i+1)*h/(TESTS_NUM-1),v-ress[i+1]/PERCENT_MAX*v,0);
|
||||
dc->color=GREEN;
|
||||
GrPrint(dc,i*h/(TESTS_NUM-1),v-FONT_HEIGHT,"10e%d",i+TEST_MIN);
|
||||
GrLine(dc,i*h/(TESTS_NUM-1),0,i*h/(TESTS_NUM-1),v);
|
||||
}
|
||||
PressAKey;
|
||||
|
||||
DCFill;
|
||||
DCDel(dc);
|
||||
}
|
||||
|
||||
MPAdd;
|
||||
@@ -0,0 +1,17 @@
|
||||
U0 Job(CDoc *doc)
|
||||
{
|
||||
I64 i;
|
||||
for (i=0;i<2;i++)
|
||||
DocPrint(doc,"$$FG,%d$$CPU%d ",Gs->num&15,Gs->num);
|
||||
}
|
||||
|
||||
U0 MPPrintDemo()
|
||||
{
|
||||
I64 i;
|
||||
for (i=0;i<500;i++)
|
||||
JobQue(&Job,DocPut,i%mp_cnt);
|
||||
Sleep(500);
|
||||
"$$FG$$\n";
|
||||
}
|
||||
|
||||
MPPrintDemo;
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
On an 8-core machine, this takes the top 3-bits
|
||||
of random numbers and distributes them to the 8 cores
|
||||
for sorting. Then, it merge sorts them.
|
||||
*/
|
||||
|
||||
#define NUM 1000000
|
||||
|
||||
I64 my_mp_cnt=1<<Bsr(mp_cnt);//Power of 2
|
||||
|
||||
I32 *arg1,*arg2;
|
||||
I32 *b[my_mp_cnt],bn[my_mp_cnt];
|
||||
I64 mp_not_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",A="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 equ 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 equ
|
||||
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)
|
||||
{
|
||||
no_warn dummy;
|
||||
QSortU32(b[Gs->num],bn[Gs->num]);
|
||||
LBtr(&mp_not_done_flags,Gs->num);
|
||||
}
|
||||
|
||||
U0 MPRadixSortDemo(I64 dummy=0)
|
||||
{
|
||||
no_warn dummy;
|
||||
I64 i,j,k1,k2;
|
||||
F64 t0;
|
||||
arg1=MAlloc(NUM*sizeof(I32));
|
||||
for (i=0;i<NUM;i++)
|
||||
arg1[i]=RandI32;
|
||||
|
||||
arg2=MAlloc(NUM*sizeof(I32));
|
||||
|
||||
"$$GREEN$$QSort$$FG$$\n";
|
||||
t0=tS;
|
||||
MemCpy(arg2,arg1,sizeof(I32)*NUM);
|
||||
QSort(arg2,NUM,sizeof(I32),&Compare);
|
||||
"Time:%9.6f\n",tS-t0;
|
||||
D(arg2+NUM/4);
|
||||
|
||||
"$$GREEN$$QSortU32$$FG$$\n";
|
||||
t0=tS;
|
||||
MemCpy(arg2,arg1,sizeof(I32)*NUM);
|
||||
QSortU32(arg2,NUM);
|
||||
"Time:%9.6f\n",tS-t0;
|
||||
D(arg2+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('MultCore');
|
||||
|
||||
"$$GREEN$$MP Radix QSortU32$$FG$$\n";
|
||||
t0=tS;
|
||||
k1=32-Bsr(my_mp_cnt);
|
||||
k2=my_mp_cnt/2;
|
||||
for (i=0;i<NUM;i++) {
|
||||
j=arg1[i]>>k1+k2; //This is a preliminary radix sort.
|
||||
b[j][bn[j]++]=arg1[i];
|
||||
}
|
||||
mp_not_done_flags=1<<my_mp_cnt-1;
|
||||
for (i=0;i<my_mp_cnt;i++)
|
||||
Spawn(&MPSort,NULL,NULL,i);
|
||||
while (mp_not_done_flags)
|
||||
Yield;
|
||||
j=0;
|
||||
for (i=0;i<my_mp_cnt;i++) {
|
||||
MemCpy(&arg2[j],b[i],bn[i]*sizeof(I32));
|
||||
j+=bn[i];
|
||||
}
|
||||
"Time:%9.6f\n",tS-t0;
|
||||
D(arg2+NUM/4);
|
||||
|
||||
Free(arg1);
|
||||
Free(arg2);
|
||||
for (i=0;i<my_mp_cnt;i++)
|
||||
Free(b[i]);
|
||||
}
|
||||
|
||||
MPRadixSortDemo;
|
||||
|
||||
/*$HL,0$ Results on 8 Cores 3.397GHz Core i7:
|
||||
$FG,2$QSort$FG$
|
||||
Time: 0.759998
|
||||
$FG,2$QSortU32$FG$
|
||||
Time: 0.093684
|
||||
$FG,2$MP Radix QSortU32$FG$
|
||||
Time: 0.045450
|
||||
$HL,1$*/
|
||||
@@ -0,0 +1,96 @@
|
||||
#define BORDER_CHARS 1
|
||||
|
||||
U8 *buf;
|
||||
I64 size,mp_not_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;
|
||||
DocPrint(doc,"CPU%02X Len:%2d ",Gs->num,len);
|
||||
while (len--)
|
||||
DocPrint(doc,"%C",*a++); //%C is toupper char
|
||||
DocPrint(doc,"\n");
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
U0 MPPalindrome(I64 dummy=0)
|
||||
{
|
||||
no_warn 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++;
|
||||
}
|
||||
LBtr(&mp_not_done_flags,Gs->num);
|
||||
}
|
||||
|
||||
U0 Palindrome(U8 *filename)
|
||||
{
|
||||
I64 i;
|
||||
F64 t0=tS;
|
||||
|
||||
buf=FileRead(filename,&size);
|
||||
PDNormalize;
|
||||
|
||||
doc=DocPut;
|
||||
mp_not_done_flags=1<<mp_cnt-1;
|
||||
for (i=0;i<mp_cnt;i++)
|
||||
JobQue(&MPPalindrome,NULL,i);
|
||||
while (mp_not_done_flags)
|
||||
Yield;
|
||||
|
||||
Free(buf);
|
||||
"Time:%9.5f\n",tS-t0;
|
||||
}
|
||||
|
||||
Palindrome(BIBLE_FILENAME);
|
||||
@@ -0,0 +1,75 @@
|
||||
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=tS,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=0;i<my_mp_cnt;i++)
|
||||
JobQue(&PrimesJob,i,i);
|
||||
while (pending)
|
||||
Yield;
|
||||
tf=tS;
|
||||
|
||||
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$$RED$$CPUs:%d PrimeRange:%,d PrimeCnt:%,d Time:%9.7,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);
|
||||
Reference in new issue
Block a user