Initial (manual) import

This commit is contained in:
minexew committed 2017-01-22 20:26:44 +01:00
1 parent f39611c506
commit 895fe109de
661 files changed
+245862

No files matched your search

+23
View File
@@ -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;
+48
View File
@@ -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;
+52
View File
@@ -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;
+85
View File
@@ -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;
+17
View File
@@ -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;
+142
View File
@@ -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$*/
+96
View File
@@ -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);
+75
View File
@@ -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);