Skip to content

Commit

Permalink
Adding new docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Ovadia committed Aug 21, 2023
1 parent 12e4f64 commit ba4b474
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 0 deletions.
68 changes: 68 additions & 0 deletions docs/Allocators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

# Sparse Array

A sparse array is conceptually an array of optionals (we could even have the backend lower optionals arrays to sparse arrays).

A sparse array will look like this:

```
struct SparseArray_Ship {
uint64_t slicesAvailableSlots[0]; // Goes backwards in memory
uint64_t capacity;
Ship[] ships;
};
```

A "slice" is a part of the array that's up to 64 elements long. If capacity <= 64, then `slicesAvailableSlots` has 1 u64. If <= 128, there are 2 u64, and so on.

Each slice's integer will have some bits, each corresponding to a slot in the array, 0 to represent available, 1 for unavailable. Anything for past the end of the array will contain 1.

The `findFirstEmpty` function will loop over `slicesAvailableSlots`, doing `count_lzero(slicesAvailableSlots[i])` to check if there are any 1s that we can use. We can unroll that loop to pipeline a little better too, and maybe even SIMD it.


# Sparse List

This is really just a sparse array that has a `size`, to know when it needs to expand.

```
struct SparseListData_Ship {
uint64_t[] availabilities; // goes backwards
Ship[] ships; // Goes forwards
};
struct SparseList_Ship {
uint64_t capacity;
uint64_t size;
SparseListData_Ship* data;
};
```

When `size` hits `capacity`, we reallocate the `SparseListData_Ship` to be twice as big.


# Sparse Stable Array



# Sparse Stable List

A sparse list is a linked list of exponentially bigger sparse arrays. However, there are some differences in how it would be represented.

```
struct SparseList_Ship {
uint64_t slicesAvailableSlots[0]; // Goes backwards in memory
uint64_t numSlices;
uint64_t capacity;
uint64_t size;
Ship[] ships; // Goes forwards in memory
};
```

Every ptr in the `slicesPtrsTagged` array-of-pointers is a pointer to an array of `Ship`. However, every pointer's top bit is 0 if it's pointing at the beginning of the allocation, 1 if it's pointing to the middle of the allocation.


`slices` could point at


# Bunch

123 changes: 123 additions & 0 deletions docs/concurrency/Interleaving.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@


```
results =
interleaved(4) foreach ship in myShipsList {
totalFuel = ship.leftEngine.fuel + ship.rightEngine.fuel;
if totalFuel < 10 {
set totalFuel = totalFuel * 2;
} else {
sequential { println(totalFuel); }
}
totalFuel
};
```

interleaved(4) implies unroll(4) and pure.

would become:


```
len = myShipsList.len();
results = List<i64>(len);
for (int i = 0; i < len; i += 4) {
iA = i;
iB = i + 1 < len ? i + 1 : i;
iC = i + 2 < len ? i + 2 : i;
iD = i + 3 < len ? i + 3 : i;
shipA = myShipsList.get(iA); // inlined
shipB = myShipsList.get(iB); // inlined
shipC = myShipsList.get(iC); // inlined
shipD = myShipsList.get(iD); // inlined
sleA = shipA.leftEngine; sleB = shipB.leftEngine; sleC = shipC.leftEngine; sleD = shipD.leftEngine;
slefA = sleA.fuel; slefB = sleB.fuel; slefC = sleC.fuel; slefD = sleD.fuel;
sreA = shipA.rightEngine; sreB = shipB.rightEngine; sreC = shipC.rightEngine; sreD = shipD.rightEngine;
srefA = sreA.fuel; srefB = sreB.fuel; srefC = sreC.fuel; srefD = sreD.fuel;
totalFuelA = slefA + srefA; totalFuelB = slefB + srefB; totalFuelC = slefC + srefC; totalFuelD = slefD + srefD;
condA = totalFuelA < 10; condB = totalFuelB < 10; condC = totalFuelC < 10; condD = totalFuelD < 10;
// Find a true
trueTotalFuelDefault = condB ? &totalFuelB : &totalFuelA;
trueTotalFuelDefault = condC ? &totalFuelC : trueTotalFuelDefault;
trueTotalFuelDefault = condD ? &totalFuelD : trueTotalFuelDefault;
trueTotalFuelPtrA = condA ? &totalFuelA : trueTotalFuelDefault;
trueTotalFuelPtrB = condB ? &totalFuelB : trueTotalFuelDefault;
trueTotalFuelPtrC = condC ? &totalFuelC : trueTotalFuelDefault;
trueTotalFuelPtrD = condD ? &totalFuelD : trueTotalFuelDefault;
if condA or condB or condC or condD {
// Load
trueTotalFuelA = *trueTotalFuelPtrA;
trueTotalFuelB = *trueTotalFuelPtrB;
trueTotalFuelC = *trueTotalFuelPtrC;
trueTotalFuelD = *trueTotalFuelPtrD;
// Do actual instructions
trueTotalFuelA = trueTotalFuelA * 2;
trueTotalFuelB = trueTotalFuelB * 2;
trueTotalFuelC = trueTotalFuelC * 2;
trueTotalFuelD = trueTotalFuelD * 2;
// Send back into parent scope
*trueTotalFuelPtrA = trueTotalFuelA;
*trueTotalFuelPtrB = trueTotalFuelB;
*trueTotalFuelPtrC = trueTotalFuelC;
*trueTotalFuelPtrD = trueTotalFuelD;
}
// Collect into an array
falseNextI = 0;
falseTotalFuels = [#8]i64(null);
falseTotalFuels[falseNextI] = &totalFuelA; falseNextI += !condA;
falseTotalFuels[falseNextI] = &totalFuelB; falseNextI += !condB;
falseTotalFuels[falseNextI] = &totalFuelC; falseNextI += !condC;
falseTotalFuels[falseNextI] = &totalFuelD; falseNextI += !condD;
for (int x = 0; x < falseNextI; x++) {
println(falseTotalFuels[x]);
}
trueTotalFuels[falseNext] = &totalFuelA; falseNext -= condA;
trueTotalFuels[falseNext] = &totalFuelB; falseNext -= condB;
trueTotalFuels[falseNext] = &totalFuelC; falseNext -= condC;
trueTotalFuels[falseNext] = &totalFuelD; falseNext -= condD;
set totalFuel = totalFuel * 2;
switch (trueNext) {
case 0: // None true, all false
println(trueTotalFuels[0]);
println(trueTotalFuels[1]);
println(trueTotalFuels[2]);
println(trueTotalFuels[3]);
break;
case 1: // 1 true, 3 false
set totalFuel = totalFuel * 2;
trueTotalFuels
case 2: // 2 true, 2 false
case 3: // 3 true, 1 false
}
a = get(i * 4 < len ? i * 4
}
foreach slice in myShipsList
unroll(8) pure interleaved foreach ship in myShipsList {
averageFuel = (ship.leftEngine.fuel + ship.rightEngine.fuel) / 2;
if averageFuel < 10 {
set averageFuel = averageFuel * 2;
} else {
sequential { println("hello"); }
}
};
```

0 comments on commit ba4b474

Please sign in to comment.