Skip to content

Commit

Permalink
sili revolution?!
Browse files Browse the repository at this point in the history
  • Loading branch information
EimaMei committed Oct 6, 2023
1 parent 38a17e2 commit 0202bc2
Show file tree
Hide file tree
Showing 10 changed files with 792 additions and 933 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ OUTPUT = build
NAME = test
EXE = $(OUTPUT)/$(NAME)

SRC = src/main.c
SRC = examples/benchmarking.c
FLAGS = -g -std=c99 -Wall -Wextra -Wpedantic
LIBS = -L"lib"
INCLUDE = -I"." -I"include"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Sili strives to strike a balance between having exceptional performance and flex
- A cross-platform file IO functions (`si_file_open`, `si_file_read`, `si_file_write_line_at` etc).
- `siOptional` type similar to `std::optional`.
- Cross-platform multi-thread support (`si_thread_create`, `si_thread_start`, `si_thread_join`).
- Easy to use benchmarking functions to check performance (`si_performance_loop`, `si_performance_exec_per_ms`), while logging how many allocations/frees were done when the `SI_MEMORY_LOGGING` macro is enabled.
- Easy to use benchmarking functions to check performance (`si_performance_loop`, `si_performance_exec_per_ms`).
- An allocator system in place, removing the need to do `free(<ptr>)` every so lines. Not only that, but it's 3x times faster than the traditional separate mallocing/freeing system.
- Bit manipulation funcionts (`si_num_count_bit`, `si_num_rotate_left`, `si_bytes_to_num`, `si_num_change_endian` etc).
- ... and more to come!
Expand Down
98 changes: 50 additions & 48 deletions examples/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,42 @@
#include <sili.h>


void example_2_0(siAllocator* heap) {
printf("==============\n\n==============\nExample 2.0:\n");
void example1(siAllocator* heap) {
si_allocatorReset(heap);
printf("==============\n\n==============\nExample 1:\n");

siArray(i32) array = si_array_make(heap, (i32[]){3, 234, 2, 4, 294, 234, 23});
siArray(i32) array = si_arrayMake(heap, (i32[]){3, 234, 2, 4, 294, 234, 23});

print("All of the elements in 'array':");
for_range (i, 0, si_array_len(array)) {
for_range (i, 0, si_arrayLen(array)) {
printf("\tElement %zd: %i\n", i, array[i]);
}

isize find_pos = si_array_find(array, 234);
isize rfind_pos = si_array_rfind(array, 234);
isize find_pos = si_arrayFind(array, 234);
isize rfind_pos = si_arrayRFind(array, 234);
printf("The 1st number '234' is at 'array[%zd]', while the 2nd one is at 'array[%zd]'\n", find_pos, rfind_pos);

usize previous_len = si_array_len(array);
si_array_append(&array, INT32_MAX); /* si_array_push does the same thing. */
usize previous_len = si_arrayLen(array);
si_arrayAppend(&array, INT32_MAX); /* si_array_push does the same thing. */

i32 front = si_any_get(i32, si_array_front(array));
i32 back = si_any_get(i32, si_array_back(array));
printf("We now have %zd elements instead of %zd. The front value is '%i', while the back value is '0x%X'\n", si_array_len(array), previous_len, front, back);
i32* front = si_arrayFront(array);
i32* back = si_arrayBack(array);
printf("We now have %zd elements instead of %zd. The front value is '%i', while the back value is '0x%X'\n", si_arrayLen(array), previous_len, *front, *back);

si_array_replace(&array, 4, INT32_MIN);
printf("The element at position '%d' was replaced with: -'-0x%X'\n", 3, array[3]);
si_arrayReplace(&array, 4, INT32_MIN);
printf("The element at position '%d' was replaced with: -'%i'\n", 3, array[3]);

siArray(i32) copy = si_array_copy(heap, array);
bool res = si_array_equal(array, copy);
siArray(i32) copy = si_arrayCopy(heap, array);
b32 res = si_arrayEqual(array, copy);

printf("Arrays 'array' and 'copy' are %s\n", (res ? "the same" : "NOT the same"));
}

void example_2_1(siAllocator* heap) {
printf("==============\n\n==============\nExample 2.1:\n");
void example2(siAllocator* heap) {
si_allocatorReset(heap);
printf("==============\n\n==============\nExample 2:\n");


siArray(i32) array = si_array_make(
siArray(i32) array = si_arrayMake(
heap,
si_buf(i32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
);
Expand All @@ -48,71 +49,72 @@ void example_2_1(siAllocator* heap) {
printf("\n");


si_array_reverse(&array);
si_arrayReverse(array);

printf("Array in reverse order: ");
for_range (num, 0, si_array_len(array)) {
for_range (num, 0, si_arrayLen(array)) {
printf("%i ", array[num]);
}
printf("\n");
}


void example_2_2(siAllocator* heap) {
siArray(siColor) array = si_array_make(
void example3(siAllocator* heap) {
si_allocatorReset(heap);
printf("==============\n\n==============\nExample 3:\n");

siArray(siColor) array = si_arrayMake(
heap,
si_buf(siColor, SI_RGB(255, 0, 0), SI_RGBA(0, 255, 0, 127), SI_RGB(0, 0, 255))
);

si_array_append(&array, (siColor){255, 255, 255, 255});
si_arrayAppend(&array, (siColor){255, 255, 255, 255});

printf("All of the elements in 'array' (len - '%zd'):\n", si_array_len(array));
for_range (i, 0, si_array_len(array)) {
printf("All of the elements in 'array' (len - '%zd'):\n", si_arrayLen(array));
for_range (i, 0, si_arrayLen(array)) {
printf("\tElement %zd: (%i, %i, %i, %i)\n", i, array[i].r, array[i].g, array[i].g, array[i].b);
}

si_array_pop(&array);
printf("Current length now - '%zd'\n", si_array_len(array));
si_arrayPop(&array);
printf("Current length now - '%zd'\n", si_arrayLen(array));


si_array_insert(&array, SI_RGB(127, 127, 127), 2);
si_arrayInsert(&array, SI_RGB(127, 127, 127), 2);

printf("All of the elements in 'array' (len - '%zd'):\n", si_array_len(array));
for_range (i, 0, si_array_len(array)) {
printf("All of the elements in 'array' (len - '%zd'):\n", si_arrayLen(array));
for_range (i, 0, si_arrayLen(array)) {
printf("\tElement %zd: (%i, %i, %i, %i)\n", i, array[i].r, array[i].g, array[i].g, array[i].b);
}

si_array_erase(&array, 2);
si_arrayErase(&array, 2);

printf("All of the elements in 'array' (len - '%zd'):\n", si_array_len(array));
for_range (i, 0, si_array_len(array)) {
printf("All of the elements in 'array' (len - '%zd'):\n", si_arrayLen(array));
for_range (i, 0, si_arrayLen(array)) {
printf("\tElement %zd: (%i, %i, %i, %i)\n", i, array[i].r, array[i].g, array[i].g, array[i].b);
}

si_array_erase_count(&array, 0, 3);
printf("array_empty: '%zd', capacity: '%zd'\n", si_array_empty(array), si_array_capacity(array));
si_arrayEraseCount(&array, 0, 3);
printf("array_empty: '%u', capacity: '%zd'\n", si_arrayEmpty(array), si_arrayCapacity(array));

si_array_fill(&array, 0, si_array_capacity(array), SI_RGBA(0xFF, 0xFF, 0xFF, 0xFF));
si_arrayFill(&array, 0, si_arrayCapacity(array), SI_RGBA(0xFF, 0xFF, 0xFF, 0xFF));

printf("All of the elements in 'array' (len - '%zd'):\n", si_array_len(array));
for_range (i, 0, si_array_len(array)) {
printf("All of the elements in 'array' (len - '%zd'):\n", si_arrayLen(array));
for_range (i, 0, si_arrayLen(array)) {
printf("\tElement %zd: (%i, %i, %i, %i)\n", i, array[i].r, array[i].g, array[i].g, array[i].b);
}

si_array_remove_item(&array, SI_RGBA(0xFF, 0xFF, 0xFF, 0xFF));
printf("All of the elements in 'array' (len - '%zd'):\n", si_array_len(array));
si_arrayRemoveItem(&array, SI_RGBA(0xFF, 0xFF, 0xFF, 0xFF));
printf("All of the elements in 'array' (len - '%zd'):\n", si_arrayLen(array));
}


int main(void) {
siAllocator* heap = si_allocator_make(0xFF);

example_2_0(heap);
example_2_1(heap);
siAllocator* heap = si_allocatorMake(0xFF);

si_allocator_refresh(heap); /* This does both `si_allocator_free` and then `si_allocator_make` to refresh its contents for next allocations. */
example_2_2(heap);
example1(heap);
example2(heap);
example3(heap);

si_allocator_free(heap);
si_allocatorFree(heap);
return 0;
}
30 changes: 21 additions & 9 deletions examples/benchmarking.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
#define SI_IMPLEMENTATION 1
#include <sili.h>
#include <immintrin.h>

i32 res[4];
static i32 first[] = {10, 20, 30, 40};
static i32 second[] = {5, 5, 5, 5};

void performance_test(void) {
isize i;
for (i = 0; i < UINT16_MAX; i++);
void performanceTest(void) {
for_range (i, 0, countof(res)) {
res[i] = first[i] + second[i];
}
}

void performanceTest2(void) {
__m128i result = _mm_add_epi32(*(__m128i*)first, *(__m128i*)second);
memcpy(res, (i32*)&result, sizeof(__m128i));
}

int main(void) {
printf("Running 'performance_test()' 30000 times. Lets see how long it takes to execute that many times...\n");
si_performance_run_per_loop(30000, performance_test());
print("Running 'performanceTest()' 30000 times. Lets see how long it takes to execute that many times...");
si_benchmarkRunsPerLoop(30000, performanceTest());

print("Now let's see how many times 'performanceTest()' can be executed in 5 seconds...");
si_benchmarkExecutesPerMs(5000, performanceTest());

printf("Now lets see how many times 'performance_test()' can be executed in 5 seconds...\n");
si_performance_executes_per_ms(5000, performance_test());
print("The average performance:");
si_benchmarkLoopsAvg(10000, performanceTest());

printf("The average performance:\n");
si_performance_loops_average(10000, performance_test());
print("Now we will compare the performance between 'performanceTest()' and 'performanceTest2()':");
si_benchmarkLoopsAvgCmp(10000, performanceTest(), performanceTest2());

return 0;
}
51 changes: 26 additions & 25 deletions examples/bit.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#define SI_IMPLEMENTATION
#include <sili.h>

inline cstring operating_system(void) {
inline cstring operatingSystem(void) {
static char res[] =
#if defined(SI_SYSTEM_WINDOWS)
"Windows"
Expand All @@ -22,7 +22,7 @@ inline cstring operating_system(void) {
}


inline cstring cpu_arch(void) {
inline cstring cpuArch(void) {
static char res[] =
#if defined(SI_CPU_X86)
"x86"
Expand Down Expand Up @@ -56,8 +56,8 @@ inline usize cpu_arch_bit(void) {
#endif
}

inline cstring cpu_endian(void) {
return (SI_LITTLE_ENDIAN == true) ? "little-endian" : "big-endian";
inline cstring cpuEndian(void) {
return (SI_HOST_IS_LITTLE_ENDIAN == true) ? "little-endian" : "big-endian";
}

inline cstring compiler(void) {
Expand Down Expand Up @@ -131,8 +131,8 @@ inline cstring standard(void) {


int main(void) {
siAllocator* alloc = si_allocator_make_stack(SI_KILO(1));
SI_ASSERT(SI_BIT(8) == 256);
siAllocator* alloc = si_allocatorMakeStack(SI_KILO(1));
SI_STATIC_ASSERT(SI_BIT(8) == 256);

printf(
"Information about the system:\n\t"
Expand All @@ -144,49 +144,50 @@ int main(void) {
"Compiler - '%s'\n\t"
"Language - '%s' (%s)\n\n"
,
operating_system(),
cpu_arch(), cpu_arch_bit(),
cpu_endian(), SI_CACHE_LINE_SIZE,
operatingSystem(),
cpuArch(), cpu_arch_bit(),
cpuEndian(), SI_CACHE_LINE_SIZE,
compiler(), language(), standard()
);

u16 adr = 0xFFFE; /* The binary expression of 0xFFFE is '0b1111111111111110' */
printf("High bytes: '%2X', low bytes: '%2X'\n", SI_HIGH_BITS(adr), SI_LOW_BITS(adr));
printf("High bytes: '%2X', low bytes: '%2X'\n", SI_NUM_HIGH_BITS(adr), SI_NUM_LOW_BITS(adr));
printf("MSB: '%i', LSB: '%i'\n", SI_BIT_MSB(adr), SI_BIT_LSB(adr));

printf("Bit 0 of 0b10: '%i'\n", SI_NUM_GET_BIT(2, 0));
printf("'usize' contains '%zd' bits on this CPU architecture.\n", SI_BYTE_TO_BIT(sizeof(usize)));
printf("Bit 0 of 0b10: '%i'\n", SI_NUM_BIT_GET(2, 0));
printf("'usize' contains '%zd' bits on this CPU architecture.\n", SI_BYTE_TO_BIT(sizeof(usize)));

usize num_bits = si_num_bits_u32(adr); /* NOTE(EimaMei): On C11 and above, you can just do 'si_num_bits' and it picks the function for you depending on the number's type. */
usize num_bits = si_numCountBitsU32(adr); /* NOTE(EimaMei): On C11 and above, you can just do 'si_numCountBits' and it picks the function for you depending on the number's type. */
printf(
"Number of 1s in 'adr': '%zd', number of 0s: '%zd'\n",
num_bits, SI_BYTE_TO_BIT(sizeof(adr)) - num_bits
);

/* The binary expression of 248 is '0b11111000'. */
u8 leadTrailNum = 248;
printf(
"Leading 1s of '248': '%zd', trailing 0s: '%zd'\n",
si_num_leading_bit((u8)248, SI_BIT_ONE), si_num_trailing_bit((u8)240, SI_BIT_ZERO)
si_numLeadingBit(leadTrailNum, SI_BIT_ONE), si_numTrailingBit(leadTrailNum, SI_BIT_ZERO)
);

u32 rotate_adr = si_num_rotate_left((u32)0x00001234, 24);
printf("Rotating '0x00001234' left by 24 bits: '0x%08X'\n", rotate_adr);
u32 rotateAdr = si_numRotateLeft((u32)0x00001234, 24);
printf("Rotating '0x00001234' left by 24 bits: '0x%08X'\n", rotateAdr);

rotate_adr = si_num_rotate_right(rotate_adr, 24);
printf("Rotating '0x34000012' right by 24 bits: '0x%08X'\n", rotate_adr);
rotateAdr = si_numRotateRight(rotateAdr, 24);
printf("Rotating '0x34000012' right by 24 bits: '0x%08X'\n", rotateAdr);

printf("Reversing the bits of '0x1234567890123456' gives us: '0x%lX'\n", si_num_reverse_bits(0x1234567890123456));
printf("Reversing the bits of '0x1234567890123456' gives us: '0x%lX'\n", si_numReverseBits(0x1234567890123456));

siArray(u8) array = si_num_to_bytes(alloc, (u32)0xFF00EEAA);
printf("All of the elements in 'array' (len - '%zd'):\n", si_array_len(array));
for_range (i, 0, si_array_len(array)) {
siArray(u8) array = si_numToBytes(alloc, (u32)0xFF00EEAA);
printf("All of the elements in 'array' (len - '%zd'):\n", si_arrayLen(array));
for_range (i, 0, si_arrayLen(array)) {
printf("\tElement %zd: '0x%02X'\n", i, array[i]);
}

u32 new_num = si_bytes_to_num(array);
printf("Combining them all back, we get '0x%X'\n", new_num);
u32 newNum = si_bytesToNumSiArr(array);
printf("Combining them all back, we get '0x%X'\n", newNum);

adr = si_num_change_endian(adr);
adr = si_swap16(adr);
printf("Changing the endian of '0xFFFE' gives us '0x%X'\n", adr);

return 0;
Expand Down
Loading

0 comments on commit 0202bc2

Please sign in to comment.