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;
}
Related
I usually hear the term vectorized functions in one of two ways:
In a very high-level language when the data is passed all-at-once (or at least, in bulk chunks) to a lower-level library that does the calculations in faster way. An example of this would be python's use of numpy for array/LA-related stuff.
At the lowest level, when using a specific machine instruction or procedure that makes heavy use of them (such as YMM, ZMM, XMM register instructions).
However, it seems like the term is passed around quite generally, and I wanted to know if there's a third (or even more) ways in which it's used. And this would just be, for example, passing multiple values to a function rather than one (usually done via an array) for example:
// non-'vectorized'
#include <stdio.h>
int squared(int num) {
return num*num;
}
int main(void) {
int nums[] = {1,2,3,4,5};
for (int i=0; i < sizeof(nums)/sizeof(*nums); i++) {
int n_squared = squared(nums[i]);
printf("%d^2 = %d\n", nums[i], n_squared);
}
}
// 'vectorized'
#include <stdio.h>
void squared(int num[], int size) {
for (int i=0; i<size; i++) {
*(num +i) = num[i] * num[i];
}
}
int main(void) {
int nums[] = {1,2,3,4,5};
squared(nums, sizeof(nums)/sizeof(*nums));
for (int i=0; i < sizeof(nums)/sizeof(*nums); i++) {
printf("Squared=%d\n", nums[i]);
}
}
Is the above considered 'vectorized code'? Is there a more formal/better definition of what makes something vectorized or not?
Vectorized code, in the context you seem to be referring to, normally means "an implementation that happens to make use of Single Instruction Multiple Data (SIMD) hardware instructions".
This can sometimes mean that someone manually wrote a version of a function that is equivalent to the canonical one, but happens to make use of SIMD. More often than not, it's something that the compiler does under the hood as part of its optimization passes.
In a very high-level language when the data is passed all-at-once (or at least, in bulk chunks) to a lower-level library that does the calculations in faster way. An example of this would be python's use of numpy for array/LA-related stuff.
That's simply not correct. The process of handing off a big chunk of data to some block of code that goes through it quickly is not vectorization in of itself.
You could say "Now that my code uses numpy, it's vectorized" and be sort of correct, but only transitively. A better way to put it would be "Now that my code uses numpy, it runs a lot faster because numpy is vectorized under the hood.". Importantly though, not all fast libraries to which big chunks of data are passed at once are vectorized.
...Code examples...
Since there is no SIMD instruction in sight in either example, then neither are vectorized yet. It might be true that the second version is more likely to lead to a vectorized program. If that's the case, then we'd say that the program is more vectorizable than the first. However, the program is not vectorized until the compiler makes it so.
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
I have some C function which, among other things, does a modulo operation. So it looks something like
const int M = 641;
void func( ...parameters..) {
int x;
... some operations ...
x %= M;
... some more operations ...
}
Now, what is crucial for me is that the number M here is a constant. If I would not tell the compiler that M is a constant, then I would get much slower performance.
Currently, I am very happy with my function func( .. ) , and I want would like to extend it, so it can work on different moduli. But again, it is crucial here that these moduli are fixed. So I would like to be able to do something like
const int arrayM[] = {641, 31, 75, 81, 123};
and then have for each index in the array of constants array_M[i] a version of the function func, say func_i, which is a copy of the function func, but where array_M[i] replaces the role of M.
In practice, my array of constants arrayM[] will consist of around 600 explicit prime numbers, which I will choose in a particular way so that x % array_M[i] compiles to a very fast modulus function (for instance Mersenne primes).
My question is: How do I do this in C without making 600 copies of my function func, and changing the variable M in the code each time ?
Finally, I would like to ask the same question again for CUDA code. So if I would have a cuda-kernel, where at some point in the code a modulus M operation is carried out, and I want to have different copies of the same kernel (one for each index of array_M).
You may use a define like:
#define F(i,n) void func_##i() { printf("%d\n",n); }
#include <stdio.h>
F(1,641)
F(2,31)
...
int main() {
func_1();
func_2();
}
It is possible to obtain the same effect from a list of constant but it is much much more tricky. See recursive macro.
Most compilers will do constant propagation. You need to turn up the optimisation level high. The only way to be sure however is to examine the assembly code, or to explicitly write the code out with the constants folded in, which is ugly and hard to maintain. C++ allows you to specify a scalar as a template.
Greetings and salutations,
I am looking for information regrading design patterns for working with a large number of functions in C99.
Background:
I am working on a complete G-Code interpreter for my pet project, a desktop CNC mill. Currently, commands are sent over a serial interface to an AVR microcontroller. These commands are then parsed and executed to make the milling head move. a typical example of a line might look like
N01 F5.0 G90 M48 G1 X1 Y2 Z3
where G90, M48, and G1 are "action" codes and F5.0, X1, Y2, Z3 are parameters (N01 is the optional line number and is ignored). Currently the parsing is coming along swimmingly, but now it is time to make the machine actually move.
For each of the G and M codes, a specific action needs to be taken. This ranges from controlled motion to coolant activation/deactivation, to performing canned cycles. To this end, my current design features a function that uses a switch to select the proper function and return a pointer to that function which can then be used to call the individual code's function at the proper time.
Questions:
1) Is there a better way to resolve an arbitrary code to its respective function than a switch statement? Note that this is being implemented on a microcontroller and memory is EXTREMELY tight (2K total). I have considered a lookup table but, unfortunately, the code distribution is sparse leading to a lot of wasted space. There are ~100 distinct codes and sub-codes.
2) How does one go about function pointers in C when the names (and possibly signatures) may change? If the function signatures are different, is this even possible?
3) Assuming the functions have the same signature (which is where I am leaning), is there a way to typedef a generic type of that signature to be passed around and called from?
My apologies for the scattered questioning. Thank you in advance for your assistance.
1) Perfect hashing may be used to map the keywords to token numbers (opcodes) , which can be used to index a table of function pointers. The number of required arguments can also be put in this table.
2) You don's want overloaded / heterogeneous functions. Optional arguments might be possible.
3) your only choice is to use varargs, IMHO
I'm not an expert on embedded systems, but I have experience with VLSI. So sorry if I'm stating the obvious.
The function-pointer approach is probably the best way. But you'll need to either:
Arrange all your action codes to be consecutive in address.
Implement an action code decoder similar to an opcode decoder in a normal processor.
The first option is probably the better way (simple and small memory footprint). But if you can't control your action codes, you'll need to implement a decoder via another lookup table.
I'm not entirely sure on what you mean by "function signature". Function pointers should just be a number - which the compiler resolves.
EDIT:
Either way, I think two lookup tables (1 for function pointers, and one for decoder) is still going to be much smaller than a large switch statement. For varying parameters, use "dummy" parameters to make them all consistent. I'm not sure what the consequences of force casting everything to void-pointers to structs will be on an embedded processor.
EDIT 2:
Actually, a decoder can't be implementated with just a lookup table if the opcode space is too large. My mistake there. So 1 is really the only viable option.
Is there a better way ... than a switch statement?
Make a list of all valid action codes (a constant in program memory, so it doesn't use any of your scarce RAM), and sequentially compare each one with the received code. Perhaps reserve index "0" to mean "unknown action code".
For example:
// Warning: untested code.
typedef int (*ActionFunctionPointer)( int, int, char * );
struct parse_item{
const char action_letter;
const int action_number; // you might be able to get away with a single byte here, if none of your actions are above 255.
// alas, http://reprap.org/wiki/G-code mentions a "M501" code.
const ActionFunctionPointer action_function_pointer;
};
int m0_handler( int speed, int extrude_rate, char * message ){ // M0: Stop
speed_x = 0; speed_y = 0; speed_z = 0; speed_e = 0;
}
int g4_handler ( int dwell_time, int extrude_rate, char * message ){ // G4: Dwell
delay(dwell_time);
}
const struct parse_item parse_table[] = {
{ '\0', 0, unrecognized_action } // special error-handler
{ 'M', 0, m0_handler }, // M0: Stop
// ...
{ 'G', 4, g4_handler }, // G4: Dwell
{ '\0', 0, unrecognized_action } // special error-handler
}
ActionFunctionPointer get_action_function_pointer( char * buffer ){
char letter = get_letter( buffer );
int action_number = get_number( buffer );
int index = 0;
ActionFunctionPointer f = 0;
do{
index++;
if( (letter == parse_table[index].action_letter ) and
(action_number == parse_table[index].action_number) ){
f = parse_table[index].action_function_pointer;
};
if('\0' == parse_table[index].action_letter ){
index = 0;
f = unrecognized_action;
};
}while(0 == f);
return f;
}
How does one go about function pointers in C when the names (and
possibly signatures) may change? If the function signatures are
different, is this even possible?
It's possible to create a function pointer in C that (at different times) points to functions with more or less parameters (different signatures) using varargs.
Alternatively, you can force all the functions that might possibly be pointed to by that function pointer to all have exactly the same parameters and return value (the same signature) by adding "dummy" parameters to the functions that require fewer parameters than the others.
In my experience, the "dummy parameters" approach seems to be easier to understand and use less memory than the varargs approach.
Is there a way to typedef a generic type of that signature
to be passed around and called from?
Yes.
Pretty much all the code I've ever seen that uses function pointers
also creates a typedef to refer to that particular type of function.
(Except, of course, for Obfuscated contest entries).
See the above example and Wikibooks: C programming: pointers to functions for details.
p.s.:
Is there some reason you are re-inventing the wheel?
Could maybe perhaps one of the following pre-existing G-code interpreters for the AVR work for you, perhaps with a little tweaking?
FiveD,
Sprinter,
Marlin,
Teacup Firmware,
sjfw,
Makerbot,
or
Grbl?
(See http://reprap.org/wiki/Comparison_of_RepRap_Firmwares ).
in PHP, I have something like
function doStuff($in, $value)
{
$var = "V_" . $in;
$$var = $value;
}
Is there a way to do something similar in C?
Basically I'm trying to figure out how to make a sort of library to make working with IO pins on an AVR easier. So for example, there would be a function to set a particular pin to an OUTPUT. That pin in the AVR is part of PORTB. Setting it to an output and giving it a value requires me to reference DDRB and PORTB constants and set their values. Rather than going through all of that, I'd like to be able to call a function such as SetMode(Pin #, Mode);. I just can't figure out how to do that.
Your question is still a little unclear (as indicated by the assortment of interpretations in the answers). I'm assuming that you want to refer to pins by physical pin number. If this is not correct, please clarify your question so we can provide better answers.
Here's roughly how I would do it if someone held a gun to my head:
DISCLAIMER: I have not tested this nor been particularly careful about checking documentation. The code is written for avr-gcc/avr-libc on Linux, though it may work elsewhere.
// Map from physical pin number to associated direction register.
volatile uint8_t *ddr_map[] = {
NULL, // Vcc, GND, or some other non-IO pin.
&DDRB,
&DDRB,
&DDRC,
// etc... Values will vary for different target chips.
};
// Map from physical pin number to port mask.
uint8_t mask_map[] = {
0x00,
_BV(0),
_BV(1),
_BV(0),
// etc... Values will vary for different target chips.
}
typedef enum {
IN,
OUT
} PinDir;
void setMode(int pin, PinDir dir) {
if(dir == OUT) {
*ddr_map[pin] |= mask_map[pin];
} else {
*ddr_map[pin] &= ~mask_map[pin];
}
}
See http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass
And here's why it's not a good idea:
It doesn't abstract away any meaningful behavior (it actually removes abstraction -- the physical pin number is lower level than the logical port/pin). Moreover, the physical pin number is not necessarily the same for different package formats. The pins of PORTB may not be assigned to the same physical pin numbers on a QFP package as a PDIP package. So this code is actually more confusing.
It adds overhead. You have an extra function call (which costs cycles and stack) and two (or more) arrays used for lookups (which cost flash and RAM on the AVR unless you take special measures, in which case they cost extra cycles and flash or EEPROM) not to mention all the indirections (array lookups, pointer dereferencing) and the extra compare and branch. In desktop & web development you would be right to laugh at my concern over such small costs, but on AVR that waste has considerably more impact. (NOTE: You might be able to convince the compiler to optimize some of this out, but if you are using -Os it will be difficult. And now you're worrying about even lower level details than before...)
The provided means of manipulating pins is not so complicated as to be worth hiding in this way. You should get comfortable with converting between hexadecimal and binary in your head (it's not hard). Even if you don't want to mess with hex, the _BV() macro makes pin manipulations pretty easy (or just use (1 << x) which is more portable and will be recognized by more programmers).
By the way, PORTB, DDRB, etc. are not constants. They are variables that are tied to specific addresses or registers. Trying to modify a constant with something like CONST_THINGY |= 0x03 would produce a compiler error.
Variable variables
C does not have the feature you described. It is a low level language (it is sometimes described as "high-level assembly") that doesn't provide many fancy features (by today's standards). This is why it is the language of choice for AVR -- you want to be close to the hardware, and you don't want lots of extra overhead.
What C does have is pointers. Based on your question and comments I would guess that you aren't very familiar with them, so here's a quick explanation:
The & operator returns a pointer to a variable, and is used like this: pointer = &variable;
* actually has a couple of uses.
The first is declaring a pointer variable (i.e. a variable that holds a pointer instead of an int, char, or float): int *pointer; Notice that you have to specify what type of variable it will point at.
The second use is what is called dereferencing a pointer. Basically, this means accessing a variable through the pointer. If pointer points at variable, *pointer = 42; will set variable equal to 42, and other_var = *pointer will set other_var to the value of variable.
There is also pointer arithmetic, but that's beyond the scope of this answer.
The point of all this is that you can effectively treat variables themselves like values, storing them and passing them around. You can't really modify them in any meaningful way other than manipulating their value, but you don't need to either.
in short, no, there aren't variable variables in C.
what you could do is make some type of hashmap of the variables, with the names as the key, and use that.
Preprocessor definitions or macros are typical ways of accomplishing your desired goal in C.
C has a macro feature, and it can be used like this
#define oof(a, b) a##b
int x1 = 5;
oof(x, 1) = 10;
printf("%d", x1); //prints 10
int oof(x, 2) = 2;
printf("%d", x2); //printf 2
It can be a function, it can use other functions, it can call other macros, etc.
And here '##' is the preprocessor operator which concatenates objects next to it.
When you say pin # you are referring to the actual pin number on the physical chip right ?
if it is. You could do this.
1- create a map function that takes in the pin number and returns and corresponding PORT and PIN
ex.
You want to access pin #1 on the chip
SetMode( int pinNumber, char mode ) {
typedef struct {
int pin;
int port;
}pinValues;
pinValues pinStruct;
mapPin( &pinStruct, pinNumber ); // this resolves the pin # on the chip to a port
// and pin.
GPIO_init( pinStruct, mode ); // this initializes the pin;
}
the mapPin function should be pretty simple just create one array containing the pin numbers
ex.
say the chip has only 4 pins
const char GPIO_pin[5] = { 1,2,3,4 };
and create a struct for the port and pin corresponding to each pin #
ex
typedef struct {
int pin;
int port;
}pinPort;
pinPort pinPortStruct[5] = { (PORTA,0), (PORTA,1), (PORTB,1), (PORTB,1) };
so pin # 1 corresponds to PORTA 0
so what you do is simply search though GPIO_pin and then return the struct that corresponds to that index
for( int i = 0;i <4; i++)
{
if( pin == GPIO_pin[i] )
return pinPortStruct[i];
}
I hope this is what you need.
All AVR registers have addresses. You can use the addresses for implementing generic functions.
Depending on how many pins/ports you are talking about, it might be easiest to use a case statement:
void SetMode(int pin, int mode) {
switch (pin) {
case PIN_A:
DDRA = mode;
PORTA = mode;
break;
case PIN_B:
DDRB = mode;
PORTB = mode;
break;
...
}
}
The constants PIN_A, PIN_B, etc can be defined through #define macros or an enum. One advantage to this approach is that you can refer to all of your ports/pins using similar notation even if you have to treat some of them differently than others (each case can be different). If you have a large number of pins/ports to deal with, then this might not be the optimal approach.
For the generic case, pointers are as close as you get. C does not necessarily have any concept of names at runtime, particularly on a microcontroller (some names typically exist in an OS with dynamic linking, but even there it's not required).
For the pin number scenario, lookup tables to figure out the port, bit in port, and so on for any given number can work. That is the technique employed by Arduino, which attempts to abstract away C++ programming on the AVR. They like renaming things, for instance calling PWM signals "analogWrite", C++ "wiring" and programs "sketches", and all I/O pins are numbered after their position on the development board. The downsides are the massive confusion as soon as you're programming something other than that first board, and having to figure out the side effects buried in their library when you want to do something low level.