Update
This commit is contained in:
parent
2cf32776c0
commit
767b52f354
8 changed files with 121 additions and 60 deletions
21
books.md
Normal file
21
books.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Books
|
||||||
|
|
||||||
|
Here there will be a constantly WIP list of [books](book.md) that might be of interest to supporters of [LRS](lrs.md):
|
||||||
|
|
||||||
|
{ Let's aim for quality rather than quantity here, don't put any book that has some connection to our cause here, but rather the ones you've read and which you judge as a quality book that enriched you in some way. ~drummyfish }
|
||||||
|
|
||||||
|
- **Blackout** (2017, Elsberg): Fiction, telling a story of a large blackout in Europe that shows to really be caused by [bloated](bloat.md) tech. For [collapse](collapse.md) enjoyers this is an interesting read if only for the detailed description of the consequences a sudden loss of electric power.
|
||||||
|
- **Einstein: His Life and Universe** (Isaacson, 2008): [Einstein](einstein.md)'s biography, quite a nice read about a pretty awesome man who's image has been so distorted by the mainstream shit.
|
||||||
|
- **Flatland** (Abbott, 1884): Absolutely amazing fantasy story set in two dimensional land with characters being geometric shapes, while being a critic of society to a big degree, it discusses practical and mathematical aspects of actually living in two dimensions, how the characters see, how they build their houses etc. It is now absolutely [public domain](public_domain.md)!
|
||||||
|
- **Free as in Freedom** (Sam Williams, 2002): Free-licensed official biography of [Richard Stallman](rms.md), contains many historical details about how [free software](free_software.md) came to be, how [open source](open_source.md) spoiled it etc.
|
||||||
|
- **Free Culture** (Lessig, 2004): Creative-commons licensed (non-free but gratis) book by the founder of [Creative Commons](creative_commons.md) and [free cutlure](free_culture.md), goes into details on how copyright became abused by capitalism, why public domain is being smothered and why we must support free culture.
|
||||||
|
- **Game Engine Black Book: Doom** (Sanglard, 2019): Gratis, very nice book dissecting all the details about the legendary [Doom](doom.md) engine and its internals -- how it worked, why was it so fast, what hacks went into it, written so that a reader of any programming skill (even none) will find something interesting. A must read for fans of oldschool game programming.
|
||||||
|
- **Game Engine Black Book: Wolfenstein 3D** (Sanglard, 2019): Same as the Doom engine book from the same author, just about the older game Wolfenstein 3D, also amazing.
|
||||||
|
- **Industrial Society and Its Future** (Kaczynski, 1995): A bit boring read by the famous [Unabomber](ted_kaczynski.md), criticizing rapid technology advancement, but an important read for those who are more into politics, if only for the memes :)
|
||||||
|
- **Just for Fun** (2001): Official biography of [Linux Torvalds](torvalds.md), the original creator of [Linux](linux.md). It recounts valuable historical moments with comments by Linus himself, revealing many interesting details and also a bit of Torvalds' personality (shows some of his evil side).
|
||||||
|
- **Masters of Doom** (Kushner, 2003): Another nice book for [Doom](doom.md) fans, this time not really technical but rather just retelling the story of the game's development -- quite comfy, a lot if interesting trivia.
|
||||||
|
- **[The Jargon File](jargon_file.md)** (1975...): [Hacker culture](hacking.md) dictionary, a lot of wisdom, inside jokes, and things related to oldschool hacking.
|
||||||
|
- **Rebel Code** (Moody, 2001): A bit of a mainstream view at the whole "[open source](open_source.md)" history -- though it's a small brain business view which we have to keep in mind at all times, it's a nice introduction to the whole FOSS world for the newcomers, as the book covers most of the relevant projects and [people](people.md).
|
||||||
|
- **The Pig and the Box** (2009, MCM): A short story for kids showing the dangers of [DRM](drm.md), released under [CC0](cc0.md)!
|
||||||
|
- **Tricks of the Game Programming Gurus** (1994): Very nice, readable book, that implements a whole 90s shooter game in [C](c.md), without drowning the reader in tons of equations and smartass talk. It's written with the 90s mindset and in common language, contains many practical tricks for optimizing the code etc.
|
||||||
|
- ...
|
|
@ -1 +1,8 @@
|
||||||
# Bullshit
|
# Bullshit
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
**Simplified example of capitalist bullshit**: under [capitalism](capitalism.md) basically the whole society is based on bullshit of many kinds, small and big, creating many bullshit clusters that are all intertwined and interact in complex ways, creating one huge bullshit. For simplicity let's consider an educated isolated bullshit cluster (that we won't see that often in reality), a hypothetical [car](car.md) factory. No matter how the factory came to be, it now ended up making cars for people so that these people can drive to work at the car factory to make more cars for other people who will work to the car factory to make cars etc. -- a bullshit cycle that exists just for its own sake, just wastes natural resources and lives of people. Of course at one point all the factory employees will own a car and the factory will have no more demand for the cars, which threatens its existence. Here capitalism employs adding more bullshit: let's say they create new bullshit jobs they call something like "[smart](smart.md) car research center" -- this will create new work position, i.e. more people who will need cars to drive to work, but MAILY the job of these people will be adding [artificial obsolescence](artificial_obsolescence.md) to the cars, which will make them last much shorter time and regularly break so that they will need repairs using parts manufactured at the factory, creating more work that will need to be done and more bullshit jobs in the car repair department. Furthermore the team will make the cars completely dependent on [subscription](subscription.md) software, employing [consumerism](consumerism.md), i.e. the car will no longer be a "buy once" thing but rather something one has to keep feeding constantly (fuel, software subscription, insurance, repairs, cleaning, tire changes, and of course once in a few years just buying a new non-obsolete model), so that workers will still need to drive to work every day, perpetuating their need for being preoccupied with owning and [maintaining](maintenance.md) a car. This is a bullshit cluster society could just get rid of without any cost, on the contrary it would gain many free people who could do actually useful things like curing diseases, eliminating world hunger, creating art for others to enjoy. However if you tell a capitalist any part of this system is bullshit, he will defend it by its necessity in the system as a whole ("How will people get to work without cars?!", "Factories are needed for the economy!", "Economy is needed to drive manufacturing of cars!") -- in reality the bullshit clusterfuck spans the whole world to incredibly deep levels so you just can't make many people see it, especially when they're preoccupied with maintaining their own existence and just get by within it.
|
||||||
|
|
||||||
|
|
||||||
|
|
106
bytecode.md
106
bytecode.md
|
@ -65,63 +65,63 @@ next:
|
||||||
.
|
.
|
||||||
```
|
```
|
||||||
|
|
||||||
The bytecode this compiles to is following:
|
Here is annotated bytecode this compiles to:
|
||||||
|
|
||||||
```
|
```
|
||||||
000000: DES 00 0111 # func
|
000000: DES 00 0111 # func \ next:
|
||||||
000001: JMA 00 0100... # 20 (#14)
|
000001: JMA 00 0100... # 20 (#14) |
|
||||||
000002: COC 00 0001
|
000002: COC 00 0001 |
|
||||||
000003: MGE 00 0000
|
000003: MGE 00 0000 | $0
|
||||||
000004: CON' 00 0010 # 2 (#2)
|
000004: CON' 00 0010 # 2 (#2) | 2
|
||||||
000005: MOX 00 0000
|
000005: MOX 00 0000 | %
|
||||||
000006: DES 00 0001 # if
|
000006: DES 00 0001 # if | \ ?
|
||||||
000007: JNA 00 0000... # 16 (#10)
|
000007: JNA 00 0000... # 16 (#10) | |
|
||||||
000008: COC 00 0001
|
000008: COC 00 0001 | |
|
||||||
000009: CON' 00 0011 # 3 (#3)
|
000009: CON' 00 0011 # 3 (#3) | | 3
|
||||||
00000a: MUX 00 0000
|
00000a: MUX 00 0000 | | *
|
||||||
00000b: CON' 00 0001 # 1 (#1)
|
00000b: CON' 00 0001 # 1 (#1) | | 1
|
||||||
00000c: ADX 00 0000
|
00000c: ADX 00 0000 | | +
|
||||||
00000d: DES 00 0010 # else
|
00000d: DES 00 0010 # else | < ;
|
||||||
00000e: JMA 00 0011... # 19 (#13)
|
00000e: JMA 00 0011... # 19 (#13) | |
|
||||||
00000f: COC 00 0001
|
00000f: COC 00 0001 | |
|
||||||
000010: CON' 00 0010 # 2 (#2)
|
000010: CON' 00 0010 # 2 (#2) | | 2
|
||||||
000011: DIX 00 0000
|
000011: DIX 00 0000 | | /
|
||||||
000012: DES 00 0011 # end if
|
000012: DES 00 0011 # end if | / .
|
||||||
000013: RET 00 0000
|
000013: RET 00 0000 / .
|
||||||
000014: INI 00 0000
|
000014: INI 00 0000
|
||||||
000015: INP 00 0000
|
000015: INP 00 0000 <-
|
||||||
000016: CON' 00 0000... # 48 (#30)
|
000016: CON' 00 0000... # 48 (#30) "0"
|
||||||
000017: COC 00 0011
|
000017: COC 00 0011
|
||||||
000018: SUX 00 0000
|
000018: SUX 00 0000 -
|
||||||
000019: DES 00 0100 # loop
|
000019: DES 00 0100 # loop \ @@
|
||||||
00001a: MGE 00 0000
|
00001a: MGE 00 0000 | $0
|
||||||
00001b: CON' 00 1010 # 10 (#a)
|
00001b: CON' 00 1010 # 10 (#a) | 10
|
||||||
00001c: DIX 00 0000
|
00001c: DIX 00 0000 | /
|
||||||
00001d: CON' 00 0000... # 48 (#30)
|
00001d: CON' 00 0000... # 48 (#30) | "0"
|
||||||
00001e: COC 00 0011
|
00001e: COC 00 0011 |
|
||||||
00001f: ADX 00 0000
|
00001f: ADX 00 0000 | +
|
||||||
000020: OUT 00 0000
|
000020: OUT 00 0000 | ->
|
||||||
000021: MGE 00 0000
|
000021: MGE 00 0000 | $0
|
||||||
000022: CON' 00 1010 # 10 (#a)
|
000022: CON' 00 1010 # 10 (#a) | 10
|
||||||
000023: MOX 00 0000
|
000023: MOX 00 0000 | %
|
||||||
000024: CON' 00 0000... # 48 (#30)
|
000024: CON' 00 0000... # 48 (#30) | "0"
|
||||||
000025: COC 00 0011
|
000025: COC 00 0011 |
|
||||||
000026: ADX 00 0000
|
000026: ADX 00 0000 | +
|
||||||
000027: OUT 00 0000
|
000027: OUT 00 0000 | ->
|
||||||
000028: CON' 00 1010 # 10 (#a)
|
000028: CON' 00 1010 # 10 (#a) | 10
|
||||||
000029: OUT 00 0000
|
000029: OUT 00 0000 | ->
|
||||||
00002a: MGE 00 0000
|
00002a: MGE 00 0000 | $0
|
||||||
00002b: CON' 00 0001 # 1 (#1)
|
00002b: CON' 00 0001 # 1 (#1) | 1
|
||||||
00002c: EQX 00 0000
|
00002c: EQX 00 0000 | =
|
||||||
00002d: DES 00 0001 # if
|
00002d: DES 00 0001 # if | \ ?
|
||||||
00002e: JNA 00 0100... # 52 (#34)
|
00002e: JNA 00 0100... # 52 (#34) | |
|
||||||
00002f: COC 00 0011
|
00002f: COC 00 0011 | |
|
||||||
000030: DES 00 0101 # break
|
000030: DES 00 0101 # break | | !@
|
||||||
000031: JMA 00 1000... # 56 (#38)
|
000031: JMA 00 1000... # 56 (#38) | |
|
||||||
000032: COC 00 0011
|
000032: COC 00 0011 | |
|
||||||
000033: DES 00 0011 # end if
|
000033: DES 00 0011 # end if | / .
|
||||||
000034: CAL 00 0011 # 3 (#3)
|
000034: CAL 00 0011 # 3 (#3) | next
|
||||||
000035: DES 00 0110 # end loop
|
000035: DES 00 0110 # end loop / .
|
||||||
000036: JMA 00 1010... # 26 (#1a)
|
000036: JMA 00 1010... # 26 (#1a)
|
||||||
000037: COC 00 0001
|
000037: COC 00 0001
|
||||||
000038: END 00 0000
|
000038: END 00 0000
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
# Fight Culture
|
# Fight Culture
|
||||||
|
|
||||||
Fight culture is the [harmful](harmful.md) mindset of seeing any endeavor as a fight against something. Even such causes as aiming for establishment of [peace](peace.md) are seen as fighting the people who are against peace, which is [funny](fun.md) but also sad. Fight culture keeps, just by the constant repetition of the word *fight*, a subconscious validation of violence as justified and necessary means for achieving any goal. Fight culture is to a great degree the culture of [capitalist](capitalism.md) society (of course not exclusively), the environment of extreme competition and hostility.
|
Fight culture is the [harmful](harmful.md), mostly western mindset of seeing any endeavor as a fight against something. Even such causes as aiming for establishment of [peace](peace.md) are seen as fighting the people who are against peace, which is [funny](fun.md) but also sad. Fight culture keeps, just by the constant repetition of the word *fight*, a subconscious validation of violence as justified and necessary means for achieving any goal. Fight culture is to a great degree the culture of [capitalist](capitalism.md) society (of course not exclusively), the environment of extreme [competition](competition.md) and hostility. It fuels [war](war.md) mentality, hostility, [fear culture](fear_culture.md) (everyone is your enemy!), constant unrest leading to mental health deterioration, obsession with various kinds of protections against everything etc. It is ridiculous, our society is now one big fight: against global warming, unemployment, inflation, [unproductivity](productivity_cult.md), traffic jams, hunger, too little hunger etc. Perhaps in a few years it won't even sound so weird to say you are fighting a road when you try to get from point A to point B or that you are fighting air when riding your bike.
|
||||||
|
|
||||||
[We](lrs.md), of course, see fight culture as inherently undesirable for a good society as that needs to be based on peace, love and [collaboration](collaboration.md), not [competition](competition.md). For this reasons we never say we "fight" anything, we rather aim for goals, look for solutions, educate and sometimes reject, refuse and oppose bad concepts (e.g. fight culture itself).
|
[We](lrs.md), of course, see fight culture as highly undesirable for a [good society](less_retarded_society.md) as that needs to be based on peace, [love](love.md) and [collaboration](collaboration.md), not [competition](competition.md). For this reasons we never say we "fight" anything, we rather aim for goals, look for solutions, educate and sometimes reject, refuse and oppose bad concepts (e.g. fight culture itself).
|
||||||
|
|
||||||
|
Capitalist often say that "life is a fight". We say life is what you make it, and if for your life is a fight, it merely says you desire fight. We do not.
|
26
game_of_life.md
Normal file
26
game_of_life.md
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Game Of Life
|
||||||
|
|
||||||
|
Game of Life (sometimes just *Life*) is probably the most famous [cellular automaton](cellular_automaton.md) (mathematical simulation set on a grid of cells), which with only four simple rules gives rise to a world with patterns that seem to behave similarly to simple biological [life](life.md). It was invented in 1970 by [John Conway](john_conway.md), a famous mathematician who researched games, and has since gained popularity among programmers, mathematicians and other nerds as it's not only scientifically valuable, it is also [awesome](beauty.md) and [fun](fun.md) to play around with as a kind of [sandbox](sandbox.md) toy; it is very easy to program, play around with, modify and can be explored to great depth. The word *game* is used because what we have here is really a zero-player mathematical [game](game.md), which is furthermore completely [deterministic](determinism.md) (there is no randomness), so we only choose some starting state of the world and then watch the game "play itself". Game of Life is similar systems such as [rule 110](rule110.md) and [Langton's ant](langtons_ant.md).
|
||||||
|
|
||||||
|
Study of the game goes extremely deep, people are discovering new patterns and concepts. See e.g. LifeWiki at https://conwaylife.com/wiki/Main_Page, Catalogue at https://catagolue.hatsya.com or Life Lexicon at https://conwaylife.com/ref/lexicon/lex.htm. The Catalogue claims to have discovered 478223 distinct types of objects so far, LifeWiki has 1651 documented patterns (many with just boring numeric names, other ones with funny names like *[Cthulhu](cthulhu.md)*, *En retard*, *Meatball*, *p58 toadsucker*, *Overweight spaceship*, *Why not*, even *[Unix](unix.md)* lol).
|
||||||
|
|
||||||
|
The following is a sum up of some basic properties of the game, many of which should show why it is so significant:
|
||||||
|
|
||||||
|
- There are only four rules and they are extremely simple but at the same time they give rise to extremely complex behavior, demonstrating emergent behavior, a very important concept.
|
||||||
|
- It resembles biological [life](life.md), showing structures that come to life, move, replicate, merge, die, organize into bigger structures etc., showing that life may really arise from a few simple rules.
|
||||||
|
- It is a class 4 cellular automaton, meaning its behavior is "interesting": sometimes it behaves orderly, sometimes in chaotic ways, sometimes the state stabilizes quickly, sometimes it evolves in complex ways for very long time etc.
|
||||||
|
- It shows many other phenomena such as [chaotic behavior](chaos.md), non-chaotic behavior, self-replication, self-organization, oscillation, [self hosting](self_hosting.md) (**you can program Game of Life in Game of Life!**) etc.
|
||||||
|
- It is [Turing complete](turing_complete.md), meaning the game can be used as a universal computer, with the same computational power as any other computer.
|
||||||
|
- It is very fun to play around with. There are many creatures to discover, observe and document (making this kind of a Pokémon game lol?).
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
We have an [infinite](infinity.md), regular two dimensional grid of cells, each of which may be in one of two states: alive or dead. Each cell considers its nearest eight cells its neighbors. The game runs in discrete steps, or rounds. Every round each cell counts its neighbors' states and will set its state for the next round according to these rules:
|
||||||
|
|
||||||
|
| current state | next state alive if | next state dead if |
|
||||||
|
| ------------- | ---------------------- | --------------------------- |
|
||||||
|
| alive | 2 or 3 live neighbors | else (under/overpopulation) |
|
||||||
|
| dead | 3 live neighbors | else |
|
||||||
|
|
||||||
|
TODO: extensions, continuous, code, optimizations
|
||||||
|
|
|
@ -10,7 +10,7 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
|
||||||
- **[gprof](gprof.md) is a utility you can use to profile your code**.
|
- **[gprof](gprof.md) is a utility you can use to profile your code**.
|
||||||
- **`<stdint.h>` has fast type nicknames**, types such as `uint_fast32_t` which picks the fastest type of at least given width on given platform.
|
- **`<stdint.h>` has fast type nicknames**, types such as `uint_fast32_t` which picks the fastest type of at least given width on given platform.
|
||||||
- **Actually measure the performance** to see if your optimizations work or not. Sometimes things behave counterintuitively and you end up making your program perform worse by trying to optimize it! Also make sure that you MEASURE THE PERFORMANCE CORRECTLY, many beginners for example just try to measure run time of a single simple function call which doesn't really work, you want to try to measure something like a million of such function calls in a loop and then average the time.
|
- **Actually measure the performance** to see if your optimizations work or not. Sometimes things behave counterintuitively and you end up making your program perform worse by trying to optimize it! Also make sure that you MEASURE THE PERFORMANCE CORRECTLY, many beginners for example just try to measure run time of a single simple function call which doesn't really work, you want to try to measure something like a million of such function calls in a loop and then average the time.
|
||||||
- **Keywords such as `inline`, `static` and `const` can help compiler optimize well**.
|
- **Keywords such as `inline`, `static`, `const` and `register` can help compiler optimize well**.
|
||||||
- **Optimize the [bottlenecks](bottleneck.md)!** Optimizing in the wrong place is a complete waste of time. If you're optimizing a part of code that's taking 1% of your program's run time, you will never speed up your program by more than that 1% even if you speed up the specific part by 10000%. Bottlenecks are usually inner-most loops of the main program loop, you can identify them with [profiling](profiling.md). Generally initialization code that runs only once in a long time doesn't need much optimization -- no one is going to care if a program starts up 1 millisecond faster (but of course in special cases such as launching many processes this may start to matter).
|
- **Optimize the [bottlenecks](bottleneck.md)!** Optimizing in the wrong place is a complete waste of time. If you're optimizing a part of code that's taking 1% of your program's run time, you will never speed up your program by more than that 1% even if you speed up the specific part by 10000%. Bottlenecks are usually inner-most loops of the main program loop, you can identify them with [profiling](profiling.md). Generally initialization code that runs only once in a long time doesn't need much optimization -- no one is going to care if a program starts up 1 millisecond faster (but of course in special cases such as launching many processes this may start to matter).
|
||||||
- **You can almost always trade space (memory usage) for time (CPU demand) and vice versa** and you can also fine-tune this. You typically gain speed by precomputation (look up tables, more demanding on memory) and memory with [compression](compression.md) (more demanding on CPU).
|
- **You can almost always trade space (memory usage) for time (CPU demand) and vice versa** and you can also fine-tune this. You typically gain speed by precomputation (look up tables, more demanding on memory) and memory with [compression](compression.md) (more demanding on CPU).
|
||||||
- **[Static](static.md) things are faster and smaller than [dynamic](dynamic.md) things.** This means that things that are somehow fixed/unchangeable are better in terms of performance (and usually also safer and better testable) than things that are allowed to change during [run time](runtime.md) -- for example calling a function directly (e.g. `myVar = myFunc();`) is both faster and requires fewer instructions than calling a function by pointer (e.g. `myVar = myFuncPointer();`): the latter is more flexible but for the price of performance, so if you don't need flexibility (dynamic behavior), use static behavior. This also applies to using [constants](constant.md) (faster/smaller) vs [variables](variable.md), static vs dynamic [typing](typing.md), normal vs dynamic [arrays](array.md) etc.
|
- **[Static](static.md) things are faster and smaller than [dynamic](dynamic.md) things.** This means that things that are somehow fixed/unchangeable are better in terms of performance (and usually also safer and better testable) than things that are allowed to change during [run time](runtime.md) -- for example calling a function directly (e.g. `myVar = myFunc();`) is both faster and requires fewer instructions than calling a function by pointer (e.g. `myVar = myFuncPointer();`): the latter is more flexible but for the price of performance, so if you don't need flexibility (dynamic behavior), use static behavior. This also applies to using [constants](constant.md) (faster/smaller) vs [variables](variable.md), static vs dynamic [typing](typing.md), normal vs dynamic [arrays](array.md) etc.
|
||||||
|
@ -26,9 +26,10 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
|
||||||
- **Write [cache-friendly](cache-friendly.md) code** (minimize long jumps in memory).
|
- **Write [cache-friendly](cache-friendly.md) code** (minimize long jumps in memory).
|
||||||
- **Compare to [0](zero.md) rather than other values**. There's usually an instruction that just checks the zero flag which is faster than loading and comparing two arbitrary numbers.
|
- **Compare to [0](zero.md) rather than other values**. There's usually an instruction that just checks the zero flag which is faster than loading and comparing two arbitrary numbers.
|
||||||
- **Use [bit tricks](bit_hack.md)**, hacks for manipulating binary numbers in clever ways only using very basic operations without which one might naively write complex inefficient code with loops and branches. Example of a simple bit trick is checking if a number is power of two as `!(x & (x - 1)) && x`.
|
- **Use [bit tricks](bit_hack.md)**, hacks for manipulating binary numbers in clever ways only using very basic operations without which one might naively write complex inefficient code with loops and branches. Example of a simple bit trick is checking if a number is power of two as `!(x & (x - 1)) && x`.
|
||||||
- **Consider moving computation from run time to compile time**. E.g. if you make a resolution of your game constant (as opposed to a variable), the compiler will be able to partially precompute expressions with the display dimensions and so speed up your program (but you won't be able to dynamically change resolution).
|
- **Consider moving computation from run time to compile time**, see [preprocessor](preprocessor.md), [macros](macro.md) and [metaprogramming](metaprogramming.md). E.g. if you make a resolution of your game constant (as opposed to a variable), the compiler will be able to partially precompute expressions with the display dimensions and so speed up your program (but you won't be able to dynamically change resolution).
|
||||||
- On some platforms such as [ARM](arm.md) the first **arguments to a function may be passed via registers**, so it may be better to have fewer parameters in functions.
|
- On some platforms such as [ARM](arm.md) the first **arguments to a function may be passed via registers**, so it may be better to have fewer parameters in functions.
|
||||||
- **Optimize when you already have a working code**. As [Donald Knuth](knuth.md) put it: "premature optimization is the root of all evil". Nevertheless you should get used to simple nobrainer efficient patterns by default and just write them automatically.
|
- **Passing arguments costs something**: passing a value to a function requires a push onto the stack and later its pop, so minimizing the number of parameters a function has, using global variables to pass arguments and doing things like passing structs by pointers rather than by value can help speed. { from *Game Programming Gurus* -drummyfish }
|
||||||
|
- **Optimize when you already have a working code**. As [Donald Knuth](knuth.md) put it: "premature optimization is the root of all evil". Nevertheless you should get used to simple nobrainer efficient patterns by default and just write them automatically. Also do one optimization at a time, don't try to put in more optimizations at once.
|
||||||
- **Use your own [caches](cache.md) where they help**, for example if you're frequently working with some database item you better pull it to memory and work with it there, then write it back once you're done (as opposed to communicating with the DB there and back).
|
- **Use your own [caches](cache.md) where they help**, for example if you're frequently working with some database item you better pull it to memory and work with it there, then write it back once you're done (as opposed to communicating with the DB there and back).
|
||||||
- **[Single compilation unit](single_compilation_unit.md) (one big program without [linking](linking.md)) can help compiler optimize better** because it can see the whole code at once, not just its parts. It will also make your program compile faster.
|
- **[Single compilation unit](single_compilation_unit.md) (one big program without [linking](linking.md)) can help compiler optimize better** because it can see the whole code at once, not just its parts. It will also make your program compile faster.
|
||||||
- Search literature for **algorithms with better [complexity class](complexity_class.md)** ([sorts](sorting.md) are a nice example).
|
- Search literature for **algorithms with better [complexity class](complexity_class.md)** ([sorts](sorting.md) are a nice example).
|
||||||
|
@ -44,6 +45,7 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
|
||||||
- **Mental calculation tricks**, e.g. multiplying by one less or more than a power of two is equal to multiplying by power of two and subtracting/adding once, for example *x * 7 = x * 8 - x*; the latter may be faster as a multiplication by power of two (bit shift) and addition/subtraction may be faster than single multiplication, especially on some primitive platform without hardware multiplication. However this needs to be tested on the specific platform. Smart compilers perform these optimizations automatically, but not every compiler is high level and smart.
|
- **Mental calculation tricks**, e.g. multiplying by one less or more than a power of two is equal to multiplying by power of two and subtracting/adding once, for example *x * 7 = x * 8 - x*; the latter may be faster as a multiplication by power of two (bit shift) and addition/subtraction may be faster than single multiplication, especially on some primitive platform without hardware multiplication. However this needs to be tested on the specific platform. Smart compilers perform these optimizations automatically, but not every compiler is high level and smart.
|
||||||
- **Else should be the less likely branch**, try to make if conditions so that the if branch is the one with higher probability of being executed -- this can help branch prediction.
|
- **Else should be the less likely branch**, try to make if conditions so that the if branch is the one with higher probability of being executed -- this can help branch prediction.
|
||||||
- Similarly **order if-sequences and switch cases from most probable**: If you have a sequences of ifs such as `if (x) ... else if (y) ... else if (z) ...`, make it so that the most likely condition to hold gets checked first, then second most likely etc. Compiler most likely can't know the probabilities of the conditions so it can't automatically help with this. Do the same with the `switch` statement -- even though switch typically gets compiled to a table of jump addresses, in which case order of the cases doesn't matter, it may also get compiled in a way similar to the if sequence (e.g. as part of size optimization if the cases are sparse) and then it may matter again.
|
- Similarly **order if-sequences and switch cases from most probable**: If you have a sequences of ifs such as `if (x) ... else if (y) ... else if (z) ...`, make it so that the most likely condition to hold gets checked first, then second most likely etc. Compiler most likely can't know the probabilities of the conditions so it can't automatically help with this. Do the same with the `switch` statement -- even though switch typically gets compiled to a table of jump addresses, in which case order of the cases doesn't matter, it may also get compiled in a way similar to the if sequence (e.g. as part of size optimization if the cases are sparse) and then it may matter again.
|
||||||
|
- **Variable aliasing**: If in a function you are often accessing a variable through some complex dereference of multiple pointers, it may help to rather load it to a local variable at the start of the function and then work with that variable, as dereferencing pointers costs something. { from *Game Programming Gurus* -drummyfish }
|
||||||
- **You can save space by "squeezing" variables** -- this is a space-time tradeoff, it's a no brainer but nubs may be unaware of it -- for example you may store 2 4bit values in a single `char` variable (8bit data type), one in the lower 4bits, one in the higher 4bits (use bit shifts etc.). So instead of 16 memory-aligned booleans you may create one `int` and use its individual bits for each boolean value. This is useful in environments with extremely limited RAM such as 8bit Arduinos.
|
- **You can save space by "squeezing" variables** -- this is a space-time tradeoff, it's a no brainer but nubs may be unaware of it -- for example you may store 2 4bit values in a single `char` variable (8bit data type), one in the lower 4bits, one in the higher 4bits (use bit shifts etc.). So instead of 16 memory-aligned booleans you may create one `int` and use its individual bits for each boolean value. This is useful in environments with extremely limited RAM such as 8bit Arduinos.
|
||||||
- **Consider [lazy evaluation](lazy_evaluation.md)** (only evaluate what's actually needed).
|
- **Consider [lazy evaluation](lazy_evaluation.md)** (only evaluate what's actually needed).
|
||||||
- **You can optimize critical parts of code in [assembly](assembly.md)**, i.e. manually write the assembly code that takes most of the running time of the program, with as few and as inexpensive instructions as possible (but beware, popular compilers are very smart and it's often hard to beat them). But note that such code loses [portability](portability.md)! So ALWAYS have a C (or whatever language you are using) [fallback](fallback.md) code for other platforms, use [ifdefs](ifdef.md) to switch to the fallback version on platforms running on different assembly languages.
|
- **You can optimize critical parts of code in [assembly](assembly.md)**, i.e. manually write the assembly code that takes most of the running time of the program, with as few and as inexpensive instructions as possible (but beware, popular compilers are very smart and it's often hard to beat them). But note that such code loses [portability](portability.md)! So ALWAYS have a C (or whatever language you are using) [fallback](fallback.md) code for other platforms, use [ifdefs](ifdef.md) to switch to the fallback version on platforms running on different assembly languages.
|
||||||
|
@ -51,6 +53,7 @@ These are mainly for [C](c.md), but may be usable in other languages as well.
|
||||||
- **[Parallelism](parallelism.md) ([multithreading](multithreading.md), [compute shaders](compute_shader.md), ...) can astronomically accelerate many programs**, it is one of the most effective techniques of speeding up programs -- we can simply perform several computations at once and save a lot of time -- but there are a few notes. Firstly not all problems can be parallelized, some problem are sequential in nature, even though most problems can probably be parallelized to some degree. Secondly it is hard to do, opens the door for many new types of bugs, requires hardware support (software simulated parallelism can't work here of course) and introduces [dependencies](dependency.md); in other words it is huge [bloat](bloat.md), we don't recommend parallelization unless a very, very good reason is given. Optional use of [SIMD](simd.md) instructions can be a reasonable midway to going full parallel computation.
|
- **[Parallelism](parallelism.md) ([multithreading](multithreading.md), [compute shaders](compute_shader.md), ...) can astronomically accelerate many programs**, it is one of the most effective techniques of speeding up programs -- we can simply perform several computations at once and save a lot of time -- but there are a few notes. Firstly not all problems can be parallelized, some problem are sequential in nature, even though most problems can probably be parallelized to some degree. Secondly it is hard to do, opens the door for many new types of bugs, requires hardware support (software simulated parallelism can't work here of course) and introduces [dependencies](dependency.md); in other words it is huge [bloat](bloat.md), we don't recommend parallelization unless a very, very good reason is given. Optional use of [SIMD](simd.md) instructions can be a reasonable midway to going full parallel computation.
|
||||||
- **Specialized hardware (e.g. a [GPU](gpu.md)) astronomically accelerates programs**, but as with the previous point, portablity and simplicity greatly suffers, your program becomes bloated and gains dependencies, always consider using specialized hardware and offer software fallbacks.
|
- **Specialized hardware (e.g. a [GPU](gpu.md)) astronomically accelerates programs**, but as with the previous point, portablity and simplicity greatly suffers, your program becomes bloated and gains dependencies, always consider using specialized hardware and offer software fallbacks.
|
||||||
- **Smaller code may also be faster** as it allows to fit more instructions into [cache](cache.md).
|
- **Smaller code may also be faster** as it allows to fit more instructions into [cache](cache.md).
|
||||||
|
- Do not optimize everything and for any cost: optimization often makes the code more cryptic, it may [bloat](bloat.md) it, bring in more bugs etc. Only optimize if it is worth the prize. { from *Game Programming Gurus* -drummyfish }
|
||||||
|
|
||||||
## When To Actually Optimize?
|
## When To Actually Optimize?
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ Palettes are related to **[screen modes](screen_mode.md)** -- systems that work
|
||||||
|
|
||||||
Using palettes has also more advantages, for example we can cycle the palette colors or quickly switch it for another palette and so e.g. increase contrast or apply some color effect (this trick was used e.g. in [Doom](doom.md)). Palettes can be constructed in clever ways (for example in [Anarch](anarch.md)) so that it is e.g. easy to make a color brighter or darker by simply incrementing or decrementing its index (while increasing brightness of a three-component RGB value is complex and slow) -- as we generally process big numbers of pixels this can lead to tremendous speed ups. Having fewer colors also makes them easier to compare and so easily implement things such as [pixel art upscaling](pixel_art_upscaling.md) (huge number of colors generally forces us to compare pixels with some amount of bias which is slower).
|
Using palettes has also more advantages, for example we can cycle the palette colors or quickly switch it for another palette and so e.g. increase contrast or apply some color effect (this trick was used e.g. in [Doom](doom.md)). Palettes can be constructed in clever ways (for example in [Anarch](anarch.md)) so that it is e.g. easy to make a color brighter or darker by simply incrementing or decrementing its index (while increasing brightness of a three-component RGB value is complex and slow) -- as we generally process big numbers of pixels this can lead to tremendous speed ups. Having fewer colors also makes them easier to compare and so easily implement things such as [pixel art upscaling](pixel_art_upscaling.md) (huge number of colors generally forces us to compare pixels with some amount of bias which is slower).
|
||||||
|
|
||||||
**Can palettes be [copyrighted](copyright.md)?** We hope not, that would indeed be pretty fucked up, however [trademarks](trademark.md) already allowed corporations to own even single colors (Milka chocolate's lilac color), and some websites for sharing palettes claim that a picture of a palette can be copyrighted as some kind of a "digital painting", even though they acknowledge a set of colors as such can't be copyrighted. So for maximum safety try to create your own palette (and share it under [CC0](cc0.md) to spare others the same pain) as a first option, as a second option use a palette that's explicitly shared under free terms ([CC0](cc0.md) is probably best), and if you absolutely have to reuse someone else's "proprietary" palette, at least reorder its colors and possibly slightly change the RGB values to make it a bit distinct.
|
**Can palettes be [copyrighted](copyright.md)?** We hope not, that would indeed be pretty fucked up, however it's not that simple, for example those massive faggots at Pantone literally try to do just that and successfully removed their "proprietary colors" from [photoshop](photoshop.md). [Trademarks](trademark.md) and [trade dress](trade_dress.md) already allowed some kind of ownership of colors or at least their combinations (Milka even tried to trademark a single color), and some websites for sharing palettes claim that a picture of a palette can be copyrighted as some kind of "digital painting", even though they acknowledge a small set of colors as such probably can't be copyrighted. In general copyright MAY apply to selection (abstract set) of things: for example a mere selection of articles from Wikipedia may be considered a copyrightable work, though of course such a "work" (lol) still has to pass some threshold of originality etc. So for maximum safety try to create your own palette (and share it under [CC0](cc0.md) and other waivers just in case, to spare others the same pain) as a first option, as a second option use some common public domain mathematically generated palette (e.g. [332](332.md)) or a palette that's explicitly shared under free terms ([CC0](cc0.md) is probably best), and if you absolutely have to reuse someone else's palette (free or proprietary), at least try to make slight modifications to it by reordering the colors and possibly slightly changing the RGB values.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ In [computer graphics](graphics.md) raycasting refers to a rendering technique i
|
||||||
|
|
||||||
{ We have an official [LRS](lrs.md) library for advanced 2D raycasting: [raycastlib](raycastlib.md)! And also a game built on top of it: [Anarch](anarch.md). ~drummyfish }
|
{ We have an official [LRS](lrs.md) library for advanced 2D raycasting: [raycastlib](raycastlib.md)! And also a game built on top of it: [Anarch](anarch.md). ~drummyfish }
|
||||||
|
|
||||||
|
{ Also there is a very cool oldschool book that goes through programming a whole raycasting game engine in C, called *Tricks of The Game Programming Gurus*, check it out! ~drummyfish }
|
||||||
|
|
||||||
2D raycasting can be used to relatively easily render "3Dish" looking environments (commonly labeled "[pseudo 3D](pseudo3D.md)"), mostly some kind of right-angled labyrinth. There are limitations such as the inability for the camera to tilt up and down (which can nevertheless be faked with shearing). It used to be popular in very old games but can still be used nowadays for "retro" looking games, games for very weak hardware (e.g. [embedded](embedded.md)), in [demos](demoscene.md) etc. It is pretty cool, very [suckless](suckless.md) rendering method.
|
2D raycasting can be used to relatively easily render "3Dish" looking environments (commonly labeled "[pseudo 3D](pseudo3D.md)"), mostly some kind of right-angled labyrinth. There are limitations such as the inability for the camera to tilt up and down (which can nevertheless be faked with shearing). It used to be popular in very old games but can still be used nowadays for "retro" looking games, games for very weak hardware (e.g. [embedded](embedded.md)), in [demos](demoscene.md) etc. It is pretty cool, very [suckless](suckless.md) rendering method.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in a new issue