Skip to content

Commit 3fb16ca

Browse files
authored
Merge pull request #17 from varmfskii/main
Thread improvement.
2 parents a31413b + 2b6105c commit 3fb16ca

File tree

10 files changed

+549
-1
lines changed

10 files changed

+549
-1
lines changed

coco/README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,75 @@
11
CPU:
2+
23
- m6809: stock in all machines, possibly m6809e, m68a09e, or
34
m68b09e. m6009e is rated at 1 MHz, m68a09e 1.5MHz, and m68b09e at
45
2MHz. All Color Computer 3 machines shipped with m68b09e or
56
equivalent.
7+
68
- h6309: common replacement (used in the late 80s, but extremely common
7-
today). Manufactures/sold as a drop in CMOS replacement with the
9+
today). Manufactured/sold as a drop in CMOS replacement with the
810
addition of a C version (3MHz). In reality it was designed with a
911
number of improvements which allow faster performance. It is also
1012
techincally 16-bits internally.
1113

1214
Systems:
15+
1316
- Dragon (various)/Color Computer 1/Color Computer 2: clocked at 0.89
1417
MHz ("slow"). Could be operated in 0.89/1.78 MHz ("fast")mode where it runs at
1518
1.78MHz which accessing routines in ROM or pure 1.78MHz mode. In
1619
1.78 MHz mode the screen is garbage and memory isn't refreshed.
20+
1721
- Color Computer 3: fully operational at both 0.89MHz ("slow") and
1822
1.78MHz ("fast").
1923

2024
Software:
25+
2126
- Color BASIC: 4-32k (64k). (Color Computer 1/2)
27+
2228
- Extended Color BASIC: 16-32k (64k) adds, in particular,
2329
support for graphics (Color Computer 1/2/Dragons)
30+
2431
- Super Extended Color BASIC: 128k adds support for some of the
2532
additional features of the GIME. (Color Computer 3), while the CoCo
2633
3 was oficially upgradable to 512k, SECB didn't really take
2734
advantage of the extra memory except for video. The code/variable
2835
for BASIC was restricted to 32k.
36+
2937
- Disk Extended Color BASIC: disk extensions for ECB or SECB.
38+
3039
- Dragon DOS: disk extensions for the Dragons.
40+
3141
- OS-9 Level I: an officially supported real OS for CoCos and Dragons
3242
with at least 64k of RAM. Basic09 was an additional package for this
3343
OS.
44+
3445
- OS-9 Level II: officially supported on CoCo 3. Adds support for MMU
3546
hardware. Each task can have its own 64k. On CoCo 3s runs at
3647
1.78MHz. Basic09 shepped with this OS (for the CoCo 3).
48+
3749
- NitrOS9: a rewrite of OS-9 originally to allow running a 6309 in
3850
native mode for faster operation. Eventually backported to support
3951
6809. Has Level I and II variants. Initially existed while CoCo 3
4052
was still in production. It is fairly common today.
53+
4154
- FLEX: another reasonably common 3rd party OS for the CoCo. Very
4255
similar to CP/M.
4356

4457
BASIC: Fast (Slow)
58+
4559
- Color Computer 1/2 or Dragon: 3:02 (4:15)
60+
4661
- Color Computer 3: 2:12 (4:26)
4762

4863
Basic09: 6809 (6309) 0:42 (0:31)
4964

5065
Assembly: 6809 (6309)
66+
5167
- Color Computer 1/2 or Dragon: 6.3 (2.7)
68+
5269
- Color Computer 3: 3.3 (1.2)
5370

5471
Assembly - Hires: 6809 (6309)
72+
5573
- Color Computer 1/2 or Dragon (128x192): 4:06 (1:17)
74+
5675
- Color Computer 3 (320x200): 5:59 (1:54)

modern/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
OPTS=-Ofast
2+
LIBS=-lpthread
3+
4+
all: mandelbrot
5+
6+
mandelbrot: mandelbrot_2.c
7+
$(CC) $(OPTS) -o $@ $^ $(LIBS)
8+
9+
.PHONY: clean distclean
10+
11+
clean:
12+
rm -f *~ *.o *# *.ppm
13+
14+
distclean: clean
15+
rm -f mandelbrot

modern/build_c.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
for i in {1,2,4,6,8,12}
4+
do
5+
echo "Speccy standard, 32x22, 15 max iteration, $i thread"
6+
gcc -o man_speccy_$i -Ofast -DWIDTH=32 -DHEIGHT=22 -DMAX_ITER=15 -DNUM_THREADS=$i mandelbrot.c -lpthread
7+
done
8+
9+
for i in {1,2,4,6,8,12}
10+
do
11+
echo "EGA/NTSC standard, 320x200, 16 max iteration, $i thread"
12+
gcc -o man_ega_$i -Ofast -DWIDTH=320 -DHEIGHT=200 -DMAX_ITER=16 -DNUM_THREADS=$i mandelbrot.c -lpthread
13+
done
14+
15+
for i in {1,2,4,6,8,12,16,24,32,48,64,96,128}
16+
do
17+
echo "4K UHD, 3840x2160, 2000 max iteration, $i thread"
18+
gcc -o man_4k_2000_$i -Ofast -DWIDTH=3840 -DHEIGHT=2160 -DMAX_ITER=2000 -DNUM_THREADS=$i mandelbrot.c -lpthread
19+
done

modern/mandelbrot.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <pthread.h>
4+
5+
#ifndef WIDTH
6+
#define WIDTH 3840
7+
#endif
8+
9+
#ifndef HEIGHT
10+
#define HEIGHT 2160
11+
#endif
12+
13+
#ifndef MAX_ITER
14+
#define MAX_ITER 2000
15+
#endif
16+
17+
#ifndef NUM_THREADS
18+
#define NUM_THREADS 12
19+
#endif
20+
21+
#if NUM_THREADS > HEIGHT
22+
#error "Can't have more threads than pixel rows!"
23+
#endif
24+
25+
void set_pixel(unsigned char *img, int x, int y, unsigned char *color);
26+
unsigned char *create_image(int w, int h);
27+
void write_ppm(char *name, int w, int h, unsigned char *img);
28+
29+
unsigned char **palette;
30+
31+
unsigned char cga_palette[16][3] = { // CGA 16-color palette, as RGB
32+
{0x00,0x00,0x00},
33+
{0x00,0x00,0xAA},
34+
{0x00,0xAA,0x00},
35+
{0x00,0xAA,0xAA},
36+
{0xAA,0x00,0x00},
37+
{0xAA,0x00,0xAA},
38+
{0xAA,0x55,0x00},
39+
{0xAA,0xAA,0xAA},
40+
{0x55,0x55,0x55},
41+
{0x55,0x55,0xFF},
42+
{0x55,0xFF,0x55},
43+
{0x55,0xFF,0xFF},
44+
{0xFF,0x55,0x55},
45+
{0xFF,0x55,0xFF},
46+
{0xFF,0xFF,0x55},
47+
{0xFF,0xFF,0xFF}
48+
};
49+
50+
int next_row=0;
51+
pthread_mutex_t lock;
52+
unsigned char *img;
53+
54+
void dorow(int py) {
55+
int px,i;
56+
double xz,yz,x,y,xt;
57+
58+
for (px=0; px<WIDTH; px++) {
59+
xz = (double)px*3.5/WIDTH-2.5;
60+
yz = (double)py*2.0/HEIGHT-1.0;
61+
x = 0.0;
62+
y = 0.0;
63+
for (i=0; i<MAX_ITER; i++) {
64+
if (x*x+y*y > 4) {
65+
break;
66+
}
67+
xt = x*x - y*y + xz;
68+
y = 2*x*y + yz;
69+
x = xt;
70+
}
71+
if (i >= MAX_ITER) {
72+
i = 0;
73+
}
74+
set_pixel(img, px, py, palette[i]);
75+
}
76+
}
77+
78+
void *rowthread(void *v) {
79+
int row;
80+
81+
for(;;) {
82+
pthread_mutex_lock(&lock);
83+
row=next_row++;
84+
pthread_mutex_unlock(&lock);
85+
if(row>=HEIGHT) break;
86+
dorow(row);
87+
}
88+
}
89+
90+
int main() {
91+
double start, end;
92+
struct timespec tspec;
93+
int py,i;
94+
pthread_t rowthreads[NUM_THREADS-1];
95+
96+
img = create_image(WIDTH, HEIGHT);
97+
palette=malloc(MAX_ITER*sizeof(unsigned char *));
98+
for (int j=0; j<MAX_ITER; j++) palette[j]=malloc(3*sizeof(unsigned char));
99+
clock_gettime(CLOCK_REALTIME, &tspec);
100+
start = tspec.tv_sec+1e-9*tspec.tv_nsec;
101+
102+
for (i=0; i<MAX_ITER; i++) {
103+
if (i<16) {
104+
palette[i][0] = cga_palette[i][0];
105+
palette[i][1] = cga_palette[i][1];
106+
palette[i][2] = cga_palette[i][2];
107+
} else if (i % 16 == 0) {
108+
palette[i][0] = i & 0x10 ? 255 : 0;
109+
palette[i][1] = i & 0x20 ? 255 : 0;
110+
palette[i][2] = i & 0x40 ? 255 : 0;
111+
if ((i & 0x70) == 0) {
112+
palette[i][0] = 255;
113+
palette[i][1] = 128;
114+
}
115+
} else {
116+
palette[i][0] = palette[i-1][0] > 16 ? palette[i-1][0] - 16 : 0;
117+
palette[i][1] = palette[i-1][1] > 16 ? palette[i-1][1] - 16 : 0;
118+
palette[i][2] = palette[i-1][2] > 16 ? palette[i-1][2] - 16 : 0;
119+
}
120+
}
121+
122+
for (i=0; i<NUM_THREADS-1; i++)
123+
pthread_create(rowthreads+i, NULL, rowthread, NULL);
124+
rowthread(NULL);
125+
for(i=0; i<NUM_THREADS-1; i++) pthread_join(rowthreads[i], NULL);
126+
127+
128+
write_ppm("mandelbrot.ppm", WIDTH, HEIGHT, img);
129+
130+
clock_gettime(CLOCK_REALTIME, &tspec);
131+
end = tspec.tv_sec+1e-9*tspec.tv_nsec;
132+
133+
printf("Elapsed Time: %f s\n", end-start);
134+
135+
return 0;
136+
}
137+
138+
unsigned char *create_image(int w, int h) {
139+
unsigned char *rv;
140+
141+
return rv = malloc(w*h*3);
142+
}
143+
144+
void set_pixel(unsigned char *img, int x, int y, unsigned char *color) {
145+
img[3*(x+y*WIDTH)+0] = color[0]; // Red
146+
img[3*(x+y*WIDTH)+1] = color[1]; // Green
147+
img[3*(x+y*WIDTH)+2] = color[2]; // Blue
148+
}
149+
150+
void write_ppm(char *name, int w, int h, unsigned char *img) {
151+
FILE *out;
152+
153+
if (!(out=fopen(name, "w"))) {
154+
fprintf(stderr, "Unable to open %s for writing\n", name);
155+
return;
156+
}
157+
fprintf(out, "P6\n%d %d\n255\n", WIDTH, HEIGHT);
158+
fwrite(img, 3, w*h, out);
159+
fclose(out);
160+
}
161+

0 commit comments

Comments
 (0)