Skip to content

Commit 0efc0e2

Browse files
Merge branch 'gcarreno:main' into main
2 parents aa11a72 + 9f0b2a8 commit 0efc0e2

File tree

6 files changed

+962
-39
lines changed

6 files changed

+962
-39
lines changed

entries/bfire/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ tabulated data for each station. Finally, the TStringList is sorted, and the da
6060

6161
## History
6262

63-
- Version 1.0: first working version, based on TStringList.
64-
- Version 1.1: modified rounding to new baseline.
65-
- Version 2.0: use hashing, sort later.
66-
- Version 2.1: minor speed tweaks.
67-
- Version 2.2: try hash functions modification.
63+
- Version 1.0: First working version, based on TStringList.
64+
- Version 1.1: Modified rounding to new baseline.
65+
- Version 2.0: Use hashing, sort later.
66+
- Version 2.1: Minor speed tweaks.
67+
- Version 2.2: Try hash functions modification.
6868
- Version 3.0: Six threads: one to read, four to tabulate, one (console) to rule them all...
69+
- Version 3.1: Safer locking strategy

entries/bfire/src/MultiThreadUnit.pas

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ THashRecord = record // each array item is compiled data for a place
4242
DataBufferSize2: Integer = 1000001;
4343
DataBufferSize3: Integer = 1000001;
4444
DataBufferSize4: Integer = 1000001;
45-
DataBufferCushion: Integer = 100000;
45+
DataBufferCushion: Integer = 10000;
4646

4747
// split points for stacks
4848
// ABCDE FGHIJK LMNOPQR STUVWXYZ (and extended)
@@ -91,12 +91,11 @@ THashRecord = record // each array item is compiled data for a place
9191
ParseDataQ_Done3: Boolean;
9292
ParseDataQ_Done4: Boolean;
9393

94-
StackMax1: Integer; // sample stack count for peak value (approx.)
94+
StackMax1: Integer; // sample stack count for peak value (approx.)
9595
StackMax2: Integer;
9696
StackMax3: Integer;
9797
StackMax4: Integer;
9898

99-
10099
procedure FileToArrays(inputFilename: String; UseStdOut: Boolean); // read
101100
procedure LaunchReadingThread(inputFilename: String);
102101
procedure LaunchTabulateThread1;
@@ -109,7 +108,6 @@ procedure ArrayToFile(outFile: String; UseStdOut: Boolean);
109108

110109
implementation
111110

112-
113111
function IntegerFixup(something: Integer): String; inline;
114112
// fixup to adjust for storing tenths of degrees as integer
115113
// e.g. convert integer 234 to string 23.4 and -167 to -16.7
@@ -124,7 +122,6 @@ function IntegerFixup(something: Integer): String; inline;
124122
IntegerFixup := thing.Replace('-.', '-0.');
125123
end;
126124

127-
128125
function MeanFixup(total: Integer; count: Integer): String; inline;
129126
// fixup to adjust for storing tenths of degrees as integer
130127
// calculate mean to one decimal place, rounded up/down depending on sign
@@ -180,7 +177,6 @@ function MeanFixup(total: Integer; count: Integer): String; inline;
180177
MeanFixup := temp; // was temp;
181178
end;
182179

183-
184180
procedure SortArrays; inline;
185181
var
186182
i: Integer;
@@ -297,7 +293,6 @@ procedure ArrayToFile(outFile: String; UseStdOut: Boolean);
297293

298294
end;
299295

300-
301296
procedure FileToArrays(inputFilename: String; UseStdOut: Boolean);
302297
var
303298
i: Integer;
@@ -362,7 +357,6 @@ procedure FileToArrays(inputFilename: String; UseStdOut: Boolean);
362357

363358
end;
364359

365-
366360
procedure LaunchReadingThread(inputFilename: String);
367361
var
368362
ReadingThread: TThread;
@@ -409,93 +403,109 @@ procedure LaunchReadingThread(inputFilename: String);
409403
if Choice <= SplitPoint1 then // A thru E
410404
begin
411405
while True do // break on success
406+
begin
407+
DataStackLock1.Acquire;
412408
if (DataStackCount1 < DataBufferSize1 - 1) then
413409
// there is room
414410
begin
415-
DataStackLock1.Acquire;
416411
DataStack1[DataStackCount1] := DataStackItem;
417412
inc(DataStackCount1);
418413
DataStackLock1.Release;
419414
Break;
420415
end
421-
else // need to waste a few cycles
416+
else // need to wait, hope for room later
422417
begin
418+
DataStackLock1.Release;
423419
while (DataStackCount1 > DataBufferSize1 -
424420
DataBufferCushion) do
425421
begin
426422
// nothing real
427-
TimeOut := DataStackCount1 mod 16001;
423+
// TimeOut := DataStackCount1 mod 16001;
424+
// TimeOut := DataStackCount1 +1;
428425
end;
429426
end;
427+
end;
430428
end
431429
else // F thru K
432430
begin
433431
while True do // break on success
432+
begin
433+
DataStackLock2.Acquire;
434434
if (DataStackCount2 < DataBufferSize2 - 1) then
435435
// there is room
436436
begin
437-
DataStackLock2.Acquire;
438437
DataStack2[DataStackCount2] := DataStackItem;
439438
inc(DataStackCount2);
440439
DataStackLock2.Release;
441440
Break;
442441
end
443-
else // need to waste a few cycles
442+
else // need to wait, hope for room later
444443
begin
444+
DataStackLock2.Release;
445445
while (DataStackCount2 > DataBufferSize2 -
446446
DataBufferCushion) do
447447
begin
448448
// nothing real
449-
TimeOut := DataStackCount2 mod 16001;
449+
// TimeOut := DataStackCount2 mod 16001;
450+
// TimeOut := DataStackCount2 +1;
450451
end;
451452
end;
453+
end;
452454
end;
453455
end
454456
else // K and beyond
455457
begin
456458
if Choice <= SplitPoint3 then // L thru R
457459
begin
458460
while True do // break on success
461+
begin
462+
DataStackLock3.Acquire;
459463
if (DataStackCount3 < DataBufferSize3 - 1) then
460464
// there is room
461465
begin
462-
DataStackLock3.Acquire;
463466
DataStack3[DataStackCount3] := DataStackItem;
464467
inc(DataStackCount3);
465468
DataStackLock3.Release;
466469
Break;
467470
end
468-
else // need to waste a few cycles
471+
else // need to wait, hope for room later
469472
begin
473+
DataStackLock3.Release;
470474
while (DataStackCount3 > DataBufferSize3 -
471475
DataBufferCushion) do
472476
begin
473477
// nothing real
474-
TimeOut := DataStackCount3 mod 16001;
478+
// TimeOut := DataStackCount3 mod 16001;
479+
// TimeOut := DataStackCount3 +1;
475480
end;
476481
end;
482+
end;
477483
end
478484
else // S and beyond
479485
begin
480486
while True do // break on success
487+
begin
488+
DataStackLock4.Acquire;
481489
if (DataStackCount4 < DataBufferSize4 - 1) then
482490
// there is room
483491
begin
484-
DataStackLock4.Acquire;
485492
DataStack4[DataStackCount4] := DataStackItem;
486493
inc(DataStackCount4);
487494
DataStackLock4.Release;
488495
Break;
489496
end
490-
else // need to waste a few cycles
497+
else // need to wait, hope for room later
491498
begin
499+
DataStackLock4.Release;
492500
while (DataStackCount4 > DataBufferSize4 -
493501
DataBufferCushion) do
494502
begin
495503
// nothing real
496-
TimeOut := DataStackCount4 mod 16001;
504+
// TimeOut := DataStackCount4 mod 16001;
505+
// TimeOut := DataStackCount4 +1;
497506
end;
498507
end;
508+
end;
499509
end;
500510
end;
501511

@@ -548,6 +558,7 @@ procedure LaunchTabulateThread1;
548558
G: Cardinal;
549559
Hash: Cardinal;
550560
BTT: Integer; // temporary for bytes to temperature conversion
561+
TimeOut: Integer;
551562

552563
begin
553564
while True do
@@ -556,9 +567,9 @@ procedure LaunchTabulateThread1;
556567
// get item from stack
557568
while True do // break on success
558569
begin
570+
DataStackLock1.Acquire;
559571
if (DataStackCount1 > 0) then // there is data
560572
begin
561-
DataStackLock1.Acquire;
562573
DataStackItem1 := DataStack1[DataStackCount1 - 1];
563574
dec(DataStackCount1);
564575
DataStackLock1.Release;
@@ -569,8 +580,12 @@ procedure LaunchTabulateThread1;
569580
if ReadFile_Done then // no more data
570581
begin
571582
ParseDataQ_Done1 := True;
583+
DataStackLock1.Release;
572584
Break;
573585
end;
586+
DataStackLock1.Release;
587+
// nothing real
588+
TimeOut := DataStackCount1 mod 16001;
574589
end;
575590
end;
576591

@@ -747,6 +762,7 @@ procedure LaunchTabulateThread2;
747762
G: Cardinal;
748763
Hash: Cardinal;
749764
BTT: Integer; // temporary for bytes to temperature conversion
765+
TimeOut: Integer;
750766

751767
begin
752768
while True do
@@ -755,9 +771,9 @@ procedure LaunchTabulateThread2;
755771
// get item from stack
756772
while True do // break on success
757773
begin
774+
DataStackLock2.Acquire;
758775
if (DataStackCount2 > 0) then // there is data
759776
begin
760-
DataStackLock2.Acquire;
761777
DataStackItem2 := DataStack2[DataStackCount2 - 1];
762778
dec(DataStackCount2);
763779
DataStackLock2.Release;
@@ -768,8 +784,12 @@ procedure LaunchTabulateThread2;
768784
if ReadFile_Done then // no more data
769785
begin
770786
ParseDataQ_Done2 := True;
787+
DataStackLock2.Release;
771788
Break;
772789
end;
790+
DataStackLock2.Release;
791+
// nothing real
792+
TimeOut := DataStackCount2 mod 16001;
773793
end;
774794
end;
775795

@@ -946,6 +966,7 @@ procedure LaunchTabulateThread3;
946966
G: Cardinal;
947967
Hash: Cardinal;
948968
BTT: Integer; // temporary for bytes to temperature conversion
969+
TimeOut: Integer;
949970

950971
begin
951972
while True do
@@ -954,9 +975,9 @@ procedure LaunchTabulateThread3;
954975
// get item from stack
955976
while True do // break on success
956977
begin
978+
DataStackLock3.Acquire;
957979
if (DataStackCount3 > 0) then // there is data
958980
begin
959-
DataStackLock3.Acquire;
960981
DataStackItem3 := DataStack3[DataStackCount3 - 1];
961982
dec(DataStackCount3);
962983
DataStackLock3.Release;
@@ -967,8 +988,12 @@ procedure LaunchTabulateThread3;
967988
if ReadFile_Done then // no more data
968989
begin
969990
ParseDataQ_Done3 := True;
991+
DataStackLock3.Release;
970992
Break;
971993
end;
994+
DataStackLock3.Release;
995+
// nothing real
996+
TimeOut := DataStackCount3 mod 16001;
972997
end;
973998
end;
974999

@@ -1147,6 +1172,7 @@ procedure LaunchTabulateThread4;
11471172
G: Cardinal;
11481173
Hash: Cardinal;
11491174
BTT: Integer; // temporary for bytes to temperature conversion
1175+
TimeOut: Integer;
11501176

11511177
begin
11521178
while True do
@@ -1155,9 +1181,9 @@ procedure LaunchTabulateThread4;
11551181
// get item from stack
11561182
while True do // break on success
11571183
begin
1184+
DataStackLock4.Acquire;
11581185
if (DataStackCount4 > 0) then // there is data
11591186
begin
1160-
DataStackLock4.Acquire;
11611187
DataStackItem4 := DataStack4[DataStackCount4 - 1];
11621188
dec(DataStackCount4);
11631189
DataStackLock4.Release;
@@ -1168,8 +1194,12 @@ procedure LaunchTabulateThread4;
11681194
if ReadFile_Done then // no more data
11691195
begin
11701196
ParseDataQ_Done4 := True;
1197+
DataStackLock4.Release;
11711198
Break;
11721199
end;
1200+
DataStackLock4.Release;
1201+
// nothing real
1202+
TimeOut := DataStackCount4 mod 16001;
11731203
end;
11741204
end;
11751205

entries/bfire/src/version.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
const
2-
cVersion = '3.0';
2+
cVersion = '3.1';

entries/hgrosser/README.md

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,37 @@
33
**1 billion row Challenge entry**
44

55
## Version
6-
Version 1.61
6+
Version 2.00 (first version with threads)
77

88
## How to compile
99
The program was developed with FPC 3.2.2 and Lazarus 2.2.4
1010

11+
1brc.lpi + 1brc.pas = version without threads
12+
13+
1brc_th.lpi + 1brc_th.pas = version with threads
14+
1115
## How to start
1216
```
13-
Usage: <path to input file> <bit-width for hash-list (16..28)>
14-
Example: hgrosser measurements.txt 16
15-
- input file: must NOT have CR's (only LF's)
16-
- bit-width for hash-list: sets the size of the hash list, e.g. '16' => 65536 entries
17+
Usage: <path to input file> <thread count> [<bit-width for hash-list> [buffer size in KB]]
18+
- thread count: allowed range = [1..32]
19+
- bit-width for hash-list: sets the size of the hash list, e.g. '16' => 65536 entries,
20+
allowed range = [16..28], Default=18
21+
- buffer size in KB: allowed range = [1..2,000,000 KB], Default=128 KB
22+
Example: hgrosser measurements.txt 32 18 128
1723
```
18-
There are no switches like `-i` etc, only 2 values.
24+
There are no switches like `-i` etc, only 2..4 values.
1925

2026
### Optimizing the 2nd command line parameter
27+
This parameter sets the thread count. With my own old CPU I could only test 1..4 threads. Although I expect 32 threads to be the fastest, I would be very interested to see the results for 1, 4, 8, 16 and 32 threads. Please use for this test the defaults for the 3rd and 4th command line parameters.
2128

22-
In theory the program should run faster with greater bit-widths for the hash-list (because of less collisions), but on my own computer (8 GB RAM) in praxis a small value of 16 is the fastest way, allthough this causes many collisions.
29+
### Optimizing the 3rd command line parameter
30+
In theory the program should run faster with greater bit-widths for the hash-list (because of less collisions). On the computer of Gus - without threads - 18 bits was the fastest. Please try the values from 16 to 20 again and use '32' for the 2nd command line parameter and the default for the 4th command line parameter.
2331

24-
Please (if possible) try all values from 16 to 22 (maybe in a for-loop). Thanks a lot.
32+
### Optimizing the 4th command line parameter
33+
After the 2nd and 3rd command line parameters had been optimized, please try with them 64, 96, 128, 192 and 256 KB as the 4th command line parameter. Thanks a lot!
2534

2635
## How the program works
27-
The Program works with 1 thread.
36+
The Program works with multi threads.
2837

2938
To speed things up:
3039

@@ -40,3 +49,5 @@ To speed things up:
4049
- Version 1.51: small improvements in asm function
4150
- Version 1.60: hash-list optimized, some minor improvements, Conditional "noCR" added
4251
- Version 1.61: Conditional "noCR" constantely enabled => input files must NOT have CR's
52+
- Version 2.00: 1st version with threads
53+

0 commit comments

Comments
 (0)