Difference between a lookup table and a jump table - c

I know that jump tables are mainly used to create switch statements in assembly:
int a = 5;
switch (a){
case 5:
...
break;
...
}
In this case, jump is just a pointer to a memory address which has instructions to do case 5 work.
If i'm not mistaking, a lookup table has pre calculated results in an array? so instead of writing code to calculate them you just return the array index? Sort of like a HashMap.
Above two sound very similar to me, are they basically the same thing? One points to instructions and the other returns pre calculated results?

If i'm not mistaking, a lookup table has pre calculated results in an array? so instead of writing code to calculate them you just return the array index? Sort of like a HashMap.
Correct. What's stored at that index could be data, or a pointer to data, or a pointer to a function etc etc.
A jump table is simply a look-up table where each index corresponds to a function, most commonly implemented in C as an array of function pointers.

Jump tables are, as you mention, native code that's arranged in a way that's easy to jump to depending on integer values. If the jump table is comprised of just short jump instructions, you can multiply your switch value by 3 and add the offset of the first entry in the table and jump (JMP or CALL) to it.
Lookup tables on the other hand are just raw data. It's still stored in a packed format so you can access it through a linear operation on your index (size * index + offset), but to make use of it you use an indirect move (MOV dest, [expression]) instead of physically jumping to it.
Keep in mind that lookup tables are just an optimization, albeit a huge one, you can load values into registers with a jump table as well. This is an is-a relationship.

What happens under the hood is up the compiler. But you're right on your observations. Here is a snippet demonstrating what compilers often do to switch statements:
#include <stdio.h>
void foo(void) { printf("foo\n"); }
void bar(void) { printf("bar\n"); }
int main(void)
{
// Array of size 2 of pointer to function without arguments returning void
// Yes, declaring function pointers is not intuitive...
void (*f[2])(void);
f[0] = foo;
f[1] = bar;
int x;
printf("Enter a number (0 or 1): ");
scanf("%d", &x);
printf("Using switch\n");
switch(x) {
case 0: foo(); break;
case 1: bar(); break;
}
printf("Using array of function pointers\n");
f[x]();
}

Related

Using an array of function pointer instead of switch

Is there any difference between using function pointer array and switch.
ı wrote a code like this
// Declaritons of add-substract-multiply funcitons
void (*fun_ptr_arr[])(int, int) = {add, subtract, multiply};
unsigned int ch, a = 15, b = 10;
printf("Enter Choice: 0 for add, 1 for subtract and 2 "
"for multiply\n");
scanf("%d", &ch);
if (ch > 2) return 0;
(*fun_ptr_arr[ch])(a, b);
and ı wonder what would be better here this code or using a switch ?
(in terms of performance btw)
A switch statement with adjacent numbers are often optimized to a function pointer look-up table internally.
Historically, compilers were bad at this and function pointer tables were always faster back in the days. Nowadays performance shouldn't be an argument for either version. In fact, one drawback with a manual function pointer table is that the compiler won't be able to inline the functions, something it can otherwise do when optimizing a switch.
So you shouldn't use the function pointer version because it is faster/slower, but rather because it can improve readability and maintenance of the code.
It is for example common practice to use such function pointer tables when implementing finite state machines. Complex switch statements on the other hand, are hard to read and there's various quirks with the syntax, such as the missing break bug etc.
Finally, you can improve the readability of your code if you write like this instead:
typedef void operation_t (int op1, int op2); // function type
operation_t* const op_array[] = {add, subtract, multiply}; // read-only function pointer table
op_array[i](a, b); // call specific function

Why Swapping without third variable not working here?

I was writing the c language code for selection sort. It was working fine If the swapping was done with using Third Variable but when I changed the method of swapping without using third variable as shown in the code comment below. It is showing wrong Output( zeros at some positions).I cannot figure out why this is happening?
I have tried to swap two numbers without third variable in another program for the same type of conditions. But it is working fine there. But Why not in my selection sort program.
#include<stdio.h>
void selectsort(int * ,int);//selection sort function
int main(){
int a[5];
int i,n=5;
for(i=0;i<5;i++)
scanf("%d",&a[i]);
selectsort(a,n);
printf("Sorted Array is:\n");
for(i=0;i<5;i++)
printf("%d\n",a[i]);
}
/* Below is selection sort function definition*/
void selectsort(int*p ,int q){
int i,j,h,temp;
for(i=0;i<q-1;i++){
h=i;
for(j=i+1;j<q;j++){
if(p[h]>p[j]){
h=j;
}
}
/* below code is to swap the two numbers ( p[i] and p[h]) without
using third variable , but it is NOT WORKING here
(giving wrong output) BUT WORKING IF THIRD VARIABLE IS USED.Why?*/
p[i]=p[i]+p[h];
p[h]=p[i]-p[h];
p[i]=p[i]-p[h];
}
}
Your values of h and i are not quaranteed to be different.
Swapping in this case will not only not swap anything but also mess up your memory.
void selectsort(int*p ,int q){
int i,j,h,temp;
for(i=0;i<q-1;i++){
h=i; // <=== Here you start with identical values
for(j=i+1;j<q;j++){
if(p[h]>p[j]){
h=j; // This may or may not be executed.
}
}
// Here h can still be at same value as i.
// What happens in this case is shown in the comments below:
p[i]=p[i]+p[h]; // p[i]=p[i]+p[i]; ==> p[i] *=2;
p[h]=p[i]-p[h]; // p[i]=p[i]-p[i]; ==> p[i] = 0;
p[i]=p[i]-p[h]; // p[i]=p[i]-p[h]; ==> p[i] = 0;
}
}
You could add something like this before doing the swapping:
if (i==h)
continue;
Note:
Apart from academic cases I would not suggest using such an approach.
Swapping without a temporary variable has lots of downsides:
Only works for integer types
Needs handling for overflow etc.
Needs handling for identical storage locations.
Needs extra arithmetic operations causing more code and longer execution time
Is confusing readers and harder to maintain
It also only has one advantage
Saves stack storage for 1 variable.
If your goal is to confuse readers, then you should search for a version using XOR instead of arithmetics. ;)

Replace switch/case by #ifdef or something similar

I'm trying to replace the switch/case structure by an other tool doing the same thing but with better performance ( less execution time ... ), I have in mind the #ifdef method but I have no idea how to use it in such situation:
float k_function(float *x,float *y,struct svm_model model)
{
int i;
float sum=0.0;
switch(model.model_kernel_type)
{
case LINEAR :
return result1;
case POLY :
return result2;
case RBF :
return result3;
case SIGMOID :
return result4;
default :
return 0;
}
}
PS :
typedef enum kernel_type {LINEAR, POLY, RBF, SIGMOID};
As I already commented, I do not believe preprocessor statements are what you are looking for. To use a preprocessor conditional, model.model_kernel_type would need to be a constant defined using a #define statement.
I do not know the internals of the switch statement, as it could be O(n) or O(1) depending on how the compiler handles it. If you needed to be sure of a O(1) time complexity, you could simply replace your switch statement with a lookup table like so:
float model_type_results[4] = {result1, result2, result3, result4};
...
return model_type_results[model.model_kernel_type];
I imagine the problem is not just 1 case statement, but code that is littered with similar case statements.
The c++ virtual function table is a similar concept for avoiding these sorts of case statements proliferating through the code. It is not actually difficult to implement function table semantics in C structures.
Traditionally, they have been written as just member function pointers, but the use of a single per-class function table pointer is more space efficient if there are many objects of each class.
#ifdef is a compile-time operation, not a run-time operation. It's not the solution you are looking for here.
Honestly, if your switch only contains four cases, there's not a lot you can do to improve on it. If you're seeing any kind of slowdown here, it's in how your results are being computed (which you don't show).

Is there a way to jump to a line defined by a variable in C?

So, I have this program, where I store the line number in a variable, using
int x = __LINE__;
The value of x can keep changing.
Is it possible to jump from an arbitrary line to the one given by x, using goto or any other keyword in C?
I'm looking for something like
'keyword' x;
where the program shifts to a line defined by the variable x.
Is there a workaround if this is not possible?
The GCC compiler supports, as an extension, using labels as values so that you can work with them in a way that resembles what you're after.
It allows you to do:
void *ptr = &&label;
label:
and then
goto *ptr;
to jump to label.
This is typically useful inside the core of a virtual machine, and can of course lead to horrible spaghetti. Also, again, it's a GCC extension (also supported by Clang, I think).
NO it's not possible, one possible way to achieve something similar is to define a variable as a function pointer and once you have set the variable to
the correct function you call it.
int foo(int x) {
return x+x;
}
int (*func) (int);
func = foo;
int r = func(3);
That is possible but very painful. Suppose you have a program like this:
instruction1;
instruction2;
...
instructionn;
then you can rewrite it as:
jump:
switch(x) {
case 1:
instruction1;
case 2:
instruction2;
...
case n:
instructionn;
}
You may then insert something like:
jump:
switch(x) {
case 1:
instruction1;
case 2:
instruction2;
...
case <something>:
x = <number>;
goto jump;
...
case n:
instructionn;
}
Of course you will then encounter some problems encoding blocks like switch in such a schema, but it is always possible to translate it in this given form (not the place here to explain how). So depending on what you really have to do, I may not worth the effort.

Place function instructions successively in program memory

Say I have a program which controls some Christmas lights (this isn't the actual application, only an example). These lights have a few different calculations to determine whether a light, i, will be lit in a given frame, t. Each of i and t is a uint8_t, so it can be assumed that there are 256 lights and t will loop each 256 frames. Some light patterns could be the following:
int flash(uint8_t t, uint8_t i) {
return t&1;}
int alternate(uint8_t t, uint8_t i) {
return i&1 == t&1;}
int loop(uint8_t t, uint8_t i) {
return i == t;}
If I then wanted to implement a mode-changing system that would loop through these modes, I could use a function pointer array int (*modes)(uint8_t, uint8_t)[3]. But, since these are all such short functions, is there any way I could instead force the compiler to place the functions directly after one another in program memory, sort of like an inline array?
The idea would be that to access one of these functions wouldn't require evaluating the pointer, and you could instead tell the processor the correct function is at modes + pitch*mode where pitch is the spacing between functions (at least the length of the longest).
I ask more out of curiosity than requirement, because I doubt this would actually cause much of a speed improvement.
What you are asking for is not directly available in C. But such logic can be possible in assembler, and C compilers might utilize different assembler tricks depending on CPU, optimization level etc. Try to just make the logic small and compact, mark the different functions as static, and use an switch() block in C and look at the assembler the compiler generates.
You could use a switch statement, like:
#define FLASH 1
#define ALTERNATE 2
#define LOOP 3
int patternexecute(uint8_t t, uint8_t i, int pattern)
{
switch (pattern) {
case FLASH: return t&1;
case ALTERNATE: return i&1 == t&1;
case LOOP: return i == t;
}
return 0;
}

Resources