Skip to content

Instantly share code, notes, and snippets.

View m1lkweed's full-sized avatar

m1lkweed

View GitHub Profile
@imaami
imaami / typeof_unqual.c
Created April 15, 2023 13:17
Backport of C23's typeof_unqual in plain C18
#define typeof_unqual(x) __typeof__(((void)1, *(__typeof__(x) *)(void *)0))
int main(void) {
const int ci = 1;
typeof_unqual(ci) i1 = ci;
typeof_unqual(const int) i2 = ci;
i1 = 0;
i2 = 0;
return i1 + i2;
}
@den-mentiei
den-mentiei / debounce.c
Created July 18, 2022 13:08
Digital input signal debouncing by Kenneth A. Kuhn
/******************************************************************************
debounce.c
written by Kenneth A. Kuhn
version 1.00
This is an algorithm that debounces or removes random or spurious
transistions of a digital signal read as an input by a computer. This is
particularly applicable when the input is from a mechanical contact. An
integrator is used to perform a time hysterisis so that the signal must
persistantly be in a logical state (0 or 1) in order for the output to change
#include <stdlib.h>
#include <string.h>
#define CAPACITY 100000
typedef struct Entry {
char* key;
void* value;
struct Entry* next;
} Entry;
@Lokno
Lokno / camera.c
Last active July 20, 2022 21:44
Lines 7-24 was generated by OpenAI's davinci-codex using Lines 1-6. Lines 27-33 were generated with only Lines 25-26
// I have a plane of size A,B in 3D space. I have a camera, which is pointed dead-on at the plane. The camera is mapping the plane into a window of size X,Y.
// How far Z should the camera be away from the plane for the *entire* plane to be visible?
//
// Find the minimum distance where the entire plane is in view
float get_distance( float plane_width, float plane_height, float fov )
{
float half_width = plane_width / 2.0f;
float half_height = plane_height / 2.0f;
float half_fov = fov / 2.0f;
// This can grow a Robin Hood linear probing hash table near word-at-a-time memcpy speeds. If you're confused why I use 'keys'
// to describe the hash values, it's because my favorite perspective on Robin Hood (which I learned from Paul Khuong)
// is that it's just a sorted gap array which is MSB bucketed and insertion sorted per chain:
// https://pvk.ca/Blog/2019/09/29/a-couple-of-probabilistic-worst-case-bounds-for-robin-hood-linear-probing/
// The more widely known "max displacement" picture of Robin Hood hashing also has strengths since the max displacement
// can be stored very compactly. You can see a micro-optimized example of that here for small tables where the max displacement
// can fit in 4 bits: Sub-nanosecond Searches Using Vector Instructions, https://www.youtube.com/watch?v=paxIkKBzqBU
void grow(Table *table) {
u64 exp = 64 - table->shift;
// We grow the table downward in place by a factor of 2 (not counting the overflow area at table->end).
@MarkMendell
MarkMendell / grapheme.c
Last active February 17, 2024 06:19
Code for extended grapheme cluster breaks
// Public domain
#include <stddef.h>
#include <stdint.h>
#if 0
// Example program
int
getlenextendedgrapheme(size_t nbuf, uint8_t *buf, size_t i)
{
@Lokno
Lokno / sthread.h
Last active July 24, 2022 04:47
Single Header Library for Simple Cross-Platform Threading
// Single Header Library for Simple Cross-Platform Threading
// Author: Lokno Decker
//
// sthread_handle handle;
// STHREAD_CREATE(handle, Func, &argument );
// STHREAD_JOIN(handle);
// STHREAD_DESTROY(handle);
//
// STHREAD_RETVAL Func( void* pArguments )
// {
@csprance
csprance / barycentric_coordinates.c
Created February 9, 2021 01:53
How to calculate barycentric coordinates in houdini using vex given 3 points making up a triangle and a point p we want to get the coordinates for
// This is the point we want to find barycentric coordinates of
vector p = point(0, "P", 3);
// These are the vertices of the main triangle we want to find coordinates for
vector v1 = point(0, "P", 0),
v2 = point(0, "P", 1),
v3 = point(0, "P", 2);
// Edge Vectors of the main triangle
vector e1 = v3 - v2,
// Length-segregated string tables for length < 16. You use a separate overflow table for length >= 16.
// By segregating like this you can pack the string data in the table itself tightly without any padding. The datapath
// is uniform and efficient for all lengths < 16 by using unaligned 16-byte SIMD loads/compares and masking off the length prefix.
// One of the benefits of packing string data tightly for each length table is that you can afford to reduce the load factor
// on shorter length tables without hurting space utilization too much. This can push hole-in-one rates into the 95% range without
// too much of a negative impact on cache utilization.
// Since get() takes a vector register as an argument with the key, you want to shape the upstream code so the string to be queried
// is naturally in a vector. For example, in an optimized identifier lexer you should already have a SIMD fast path for length < 16
// The two sweetspots are 8-bit and 4-bit tags. In the latter case you can fit 14 32-bit keys in
// a cacheline-sized bucket and still have one leftover byte for metadata.
// As for how to choose tags for particular problems, Google's Swiss table and Facebook's F14 table
// both use hash bits that weren't used for the bucket indexing. This is ideal from an entropy perspective
// but it can be better to use some particular feature of the key that you'd otherwise check against anyway.
// For example, for 32-bit keys (with a usable sentinel value) you could use the 8 low bits as the tag
// while storing the remaining 24 bits in the rest of the bucket; that fits 16 keys per bucket. Or if the keys
// are strings you could store the length as the discriminator: with an 8-bit tag, 0 means an empty slot,
// 1..254 means a string of that length, and 255 means a string of length 255 or longer. With a 4-bit tag