C


A peculiar way to get the biggest (max/maximum) value between two variables using bitwise operations 3

Recently, we wanted to make a test and see how we could find the maximum value between two variables using bitwise operations.

We ended up with the following peculiar way to get the biggest value between two variables using bitwise operations


r = a ^ ((a ^ b) & -(a < b));

The above formula has two modes:

  1. When a < b
  2. When a >= b

 

When a < b then the formula will change as follows:


r = a ^ ((a ^ b) & 0xFFFFFFFF);

As we all (should) know, when one of the operators on a bitwise AND operation is composed only from 1s, then the result is whatever value the other operator was holding.
So, the formula then simplifies as follows:


r = a ^ (a ^ b);

which is equal to


r = b;

because we when we apply twice the same value using XOR on another value, we revert back to the original value (so the second ^a nullifies the first ^a)

 

When a >= b then the formula will change as follows:


r = a ^ ((a ^ b) & 0x00000000);

When one of the operators on a bitwise AND operation is composed only from 0s, then the result is always 0 no matter what value the other operator was holding.
So, the formula then simplifies as follows:


r = a ^ (0x00000000);

which is equal to


r = a;

because when one of the operators in a XOR operation is only composed from 0s then the result will be the value of the other operator, no matter what it was.

 

Full example

Below you will find a full example that compares the execution speed of the two methods by executing each several thousands of time on the same random data.

[download id=”3875″]


#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main() {
    {
        const clock_t start = clock();

        srand(10);
        unsigned long int i;
        unsigned int max = 0;
        for (i = 0; i < 1000000000; i++) {
            const int a = rand();
            max = max < a ? a : max;
        }
        const clock_t end = clock();
        const float seconds = (float) (end - start) / CLOCKS_PER_SEC;
        printf("Seconds elapsed %f\tIf statement. Overall max value = %u\n", seconds, max);
    }

    {
        const clock_t start = clock();

        srand(10);
        unsigned long int i;
        unsigned int max = 0;
        for (i = 0; i < 1000000000; i++) {
            const int a = rand();
            max = a ^ ((a ^ max) & -(a < max));
        }
        const clock_t end = clock();
        const float seconds = (float) (end - start) / CLOCKS_PER_SEC;
        printf("Seconds elapsed %f\tBitwise operation. Overall max value = %u\n", seconds, max);
    }
    return 0;
}

Results

Our results show that using the traditional if statement with assignment is faster than using our formula as expected.
Which makes sense as there is an if statement in the formula as well and then additional operations to get the result, instead of just the assignment.

Seconds elapsed 5.770000 If statement. Overall max value = 2147483647
Seconds elapsed 6.180000 Bitwise operation. Overall max value = 2147483647

10 times bigger input

Seconds elapsed 57.450001 If statement. Overall max value = 2147483647
Seconds elapsed 63.869999 Bitwise operation. Overall max value = 2147483647

C/C++: Get a random number that is in a specific range 1

Assuming you need to generate a random number that is in a specified range, you can do the following:


//int rand(void) creates a pseudo-random number in the range of 0 to RAND_MAX
//RAND_MAX is defined in stdlib.h and is the largest number rand will return (same as INT_MAX).
const int new_number = (rand() % (maximum_number + 1 - minimum_number)) + minimum_number;

The above code first creates a pseudo-random number that is in the range of [0, RAND_MAX].
Then it will divide it with the width (+1) of the range we want to use (maximum_number + 1 - minimum_number) and get the remainder (modulo).
The modulo will be in the range of [0, maximum_number - minimum_number], so we add to it the value of minimum_number to shift the result to the proper range.
This solution, as demonstrated in the example below, works for negative ranges as well.

Full example of generating 100000 random numbers that are all in the range [-31, 32].

const int maximum_number = 31;
const int minimum_number = -32;
unsigned int i;
for (i = 0; i <= 100000; i++) {
	const int new_number = (rand() % (maximum_number + 1 - minimum_number)) + minimum_number;
	printf("%d\n", new_number);
}

C/C++: Comparing the performance of syslog vs printf

The following code tries to compare the performance of syslog() with the printf() command. [download id=”3787″]
On our machine, it appears that syslog() is faster than printf().

To be as fair as possible, when the application was executing, we were monitoring the system logs as well, so that they will be printed on screen.
On CentOS 7, you can see the syslog in the file /var/log/messages.
The command we used was: sudo tail -f /var/log/messages

Results:

printf: Seconds elapsed 0.480000
syslog: Seconds elapsed 0.180000

Full source code for test:

[download id=”3787″]


#include <stdio.h>
#include <syslog.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>
// #include <time.h> is needed for the clock() function and the macro CLOCKS_PER_SEC
#include <time.h>
// #include <unistd.h> and #include <sys/types.h> are needed for the functions uid_t getuid(void); and uid_t geteuid(void);
//getuid() returns the real user ID of the calling process.
//geteuid() returns the effective user ID of the calling process.
//These functions are always successful.
#include <unistd.h>
#include <sys/types.h>

#define RANGE (100000)

int main()
{
    {
        const clock_t start = clock();

        unsigned int i;
        for (i = 0; i < RANGE; i++){
            printf ("Program started by Real User %u (Effective User %u)\n", getuid(), geteuid());
        }
        printf("\n");

        const clock_t end = clock();
        const float seconds = (float) (end - start) / CLOCKS_PER_SEC;
        printf("printf: Seconds elapsed %f\n", seconds);
    }
    {
        const clock_t start = clock();

        setlogmask (LOG_UPTO (LOG_NOTICE));
        openlog ("bytefreaks", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
        unsigned int i;
        for (i = 0; i < RANGE; i++){
            syslog (LOG_NOTICE, "Program started by Real User %u (Effective User %u)", getuid(), geteuid());
        }
        closelog ();

        const clock_t end = clock();
        const float seconds = (float) (end - start) / CLOCKS_PER_SEC;
        printf("syslog: Seconds elapsed %f\n", seconds);

    }
    return EXIT_SUCCESS;
}


[download id=”3787″]


C/C++: Set and Get the name of a pthread

Naming a pthread using meaningful names, can be a very useful feature for debugging multi-threaded applications as it can make your logs very informative.
For this reason, we are presenting two examples demonstrating the use of names in pthreads.

  • [download id=”3786″]
  • [download id=”3788″]

Example 1: The pthread decides for its name

The following code, creates a pthread which later, it will give itself a meaningful name.

[download id=”3786″]


// #define _GNU_SOURCE is needed for the resolution of the following warnings
//warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration]
//warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration]
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <asm/errno.h>
#include <errno.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>

//The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte.
#define MAX_LENGTH_PTHREAD_NAME (16)

struct thread_info_t
{
    // Used to identify a thread.
    pthread_t thread_id;
};

// This is the thread that will be called by pthread_create() and it will be executed by the new thread.
void *self_named_thread(void *data)
{
    // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type.
    struct thread_info_t *thread_info = (struct thread_info_t *) data;

    const int setname_rv = pthread_setname_np(thread_info->thread_id, "Tom Hanks");
    if (setname_rv)
    {
        errno = setname_rv;
        perror("Could not set pthread name");
    }

    char thread_name[MAX_LENGTH_PTHREAD_NAME];
    const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME);
    if (getname_rv)
    {
        errno = getname_rv;
        perror("Could not get pthread name");
    }
    //This function always succeeds, returning the calling thread's ID.
    const pthread_t tid = pthread_self();
    //Usually pthread_t is defined as follows:
    //typedef unsigned long int pthread_t;
    //so we print pthread_t as an unsigned long int
    fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and I gave me my name by myself\n", tid, thread_name );

    return NULL;
}

int main()
{
    struct thread_info_t thread_info;

    const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info);
    if (create_rv)
    {
        errno = create_rv;
        perror("Could not create thread");
        return EXIT_FAILURE;
    }
    // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated.
    const int join_rv = pthread_join(thread_info.thread_id, NULL);
    if (join_rv)
    {
        errno = create_rv;
        perror("Could not join thread");
    }
    return EXIT_SUCCESS;
}

[download id=”3786″]

Example 2: The parent decides for the pthread name

The next code, creates a pthread and the parent gives the thread a meaningful name.

[download id=”3788″]


// #define _GNU_SOURCE is needed for the resolution of the following warnings
//warning: implicit declaration of function ‘pthread_setname_np’ [-Wimplicit-function-declaration]
//warning: implicit declaration of function ‘pthread_getname_np’ [-Wimplicit-function-declaration]
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
#include <asm/errno.h>
#include <errno.h>
// #include <stdlib.h> is needed for the resolution of EXIT_SUCCESS
#include <stdlib.h>
// #include <unistd.h> is needed for the resolution of unsigned int sleep(unsigned int seconds);
#include <unistd.h>

//The thread name is a meaningful C language string, whose length is restricted to 16 characters, including the terminating null byte.
#define MAX_LENGTH_PTHREAD_NAME (16)

struct thread_info_t
{
    // Used to identify a thread.
    pthread_t thread_id;
};

// This is the thread that will be called by pthread_create() and it will be executed by the new thread.
void *self_named_thread(void *data)
{
    // We know that the input data pointer is pointing to a thread_info_t so we are casting it to the right type.
    struct thread_info_t *thread_info = (struct thread_info_t *) data;

    //Added an artificial delay for the sake of the example.
    //Making sure the parent thread gave the pthread a name.
    sleep(1);

    char thread_name[MAX_LENGTH_PTHREAD_NAME];
    const int getname_rv = pthread_getname_np(thread_info->thread_id, thread_name, MAX_LENGTH_PTHREAD_NAME);
    if (getname_rv)
    {
        errno = getname_rv;
        perror("Could not get pthread name");
    }
    //This function always succeeds, returning the calling thread's ID.
    const pthread_t tid = pthread_self();
    //Usually pthread_t is defined as follows:
    //typedef unsigned long int pthread_t;
    //so we print pthread_t as an unsigned long int
    fprintf(stdout, "I am thread with ID '%lu', my name is '%s' and my parent gave me my name\n", tid, thread_name );

    return NULL;
}

int main()
{
    struct thread_info_t thread_info;

    const int create_rv = pthread_create(&(thread_info.thread_id), NULL, &self_named_thread, (void *) &thread_info);
    if (create_rv)
    {
        errno = create_rv;
        perror("Could not create thread");
        return EXIT_FAILURE;
    }

    const int setname_rv = pthread_setname_np(thread_info.thread_id, "Bob Marley");
    if (setname_rv)
    {
        errno = setname_rv;
        perror("Could not set pthread name");
    }

    // The pthread_join() function suspends execution of the calling thread until the target thread terminates, unless the target thread has already terminated.
    const int join_rv = pthread_join(thread_info.thread_id, NULL);
    if (join_rv)
    {
        errno = create_rv;
        perror("Could not join thread");
    }
    return EXIT_SUCCESS;
}

[download id=”3788″]