Skip to content

Instantly share code, notes, and snippets.

@aprell
Last active October 26, 2021 15:35
Show Gist options
  • Select an option

  • Save aprell/9e704b06b1d82de656c05b28799dd9fd to your computer and use it in GitHub Desktop.

Select an option

Save aprell/9e704b06b1d82de656c05b28799dd9fd to your computer and use it in GitHub Desktop.
Different loop unrolling strategies
// CFLAGS="-Wall -Wextra -Wno-implicit-fallthrough"
#include <assert.h>
#include <stdio.h>
// 1) (n - (n % 4)) / 4 iterations
// 2) n % 4 iterations
void loop1(int n)
{
int i, j;
for (i = 0; i < n - 3; i += 4) {
printf("loop1-main: %d\n", i + 0);
printf("loop1-main: %d\n", i + 1);
printf("loop1-main: %d\n", i + 2);
printf("loop1-main: %d\n", i + 3);
}
assert(n - 3 <= i && i <= n);
// Post loop iterates between 0 and n - (n - 3) == 3 times
assert(n - 3 <= n - (n % 4));
assert(i % 4 == 0);
assert(i == n - (n % 4));
// n - i == n - (n - (n % 4)) == n % 4
assert(n - i == n % 4);
for (j = i; j < n; j++) {
printf("loop1-post: %d\n", j);
}
assert(j == n);
}
// 1) (n - (n % 4)) / 4 iterations
// 2) n % 4 iterations
void loop2(int n)
{
int i, j;
for (i = 0; i < n - (n % 4); i += 4) {
printf("loop2-main: %d\n", i + 0);
printf("loop2-main: %d\n", i + 1);
printf("loop2-main: %d\n", i + 2);
printf("loop2-main: %d\n", i + 3);
}
assert(i % 4 == 0);
assert(i == n - (n % 4));
// n - i == n - (n - (n % 4)) == n % 4
assert(n - i == n % 4);
for (j = i; j < n; j++) {
printf("loop2-post: %d\n", j);
}
assert(j == n);
}
// 1) n % 4 iterations
// 2) (n - (n % 4)) / 4 iterations
void loop3(int n)
{
int i, j;
for (i = 0; i < n % 4; i++) {
printf("loop3-pre: %d\n", i);
}
assert(i == n % 4);
// n - i == n - (n % 4)
assert(n - i == n - (n % 4));
for (j = i; j < n; j += 4) {
printf("loop3-main: %d\n", j + 0);
printf("loop3-main: %d\n", j + 1);
printf("loop3-main: %d\n", j + 2);
printf("loop3-main: %d\n", j + 3);
}
assert(j == n);
}
// Duff's device
void loop4(int n)
{
int i = 0;
if (n > 0) {
switch (n % 4) {
case 0: do { printf("loop4-main: %d\n", i++);
case 3: printf("loop4-main: %d\n", i++);
case 2: printf("loop4-main: %d\n", i++);
case 1: printf("loop4-main: %d\n", i++);
} while (i < n);
}
}
assert(i == n);
}
void test(int n)
{
printf(" n | n - 3 | n - (n %% 4)\n");
printf("---+-------+-------------\n");
int i;
for (i = 0; i <= n; i++) {
printf("%2d | %5d | %10d\n", i, i - 3, i - (i % 4));
}
}
int main(void)
{
int i;
for (i = 0; i <= 10; i++) {
loop1(i);
printf("\n");
}
for (i = 0; i <= 10; i++) {
loop2(i);
printf("\n");
}
for (i = 0; i <= 10; i++) {
loop3(i);
printf("\n");
}
for (i = 0; i <= 10; i++) {
loop4(i);
printf("\n");
}
//test(10);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment