2

What I'm trying to do here is to compare the performance of single-threading and multi-threading by doing a simple and repetitive operation. So I have two threads assigning this random number 0xde to this array each thread taking the first and second half of the array and single-thread does the same work by itself from index 0 to the end.

What I do not understand is that even though those sub-threads are doing half the work as the single-thread(that is, the main-thread), they're taking up more time to finish their task! I don't expect it to take half the time as single-threading, but I can't possibly imagine why it would take longer than single-threading.

And even more surprisingly, If I switch the order to do the single-threading first, then I get the result I wanted. I could really use some help on this as this is all messed up in my head. Thanks in advance!

ps. I'm using a Raspberry Pi 3 which has 4 ARM processors if that helps. This is the result I got. Multithreading1 : 46 ms
Mulththreading2 : 50 ms
Singlethreading : 34 ms

#include <pthread.h>
#include <stdio.h>
#include <time.h>
#define SIZE 1000000

clock_t difference = 0;
clock_t difference1 = 0;
clock_t difference2 = 0;

void *substitute1(void *operand)
{
    int *arr = (int *)operand;
    int i=0;
    clock_t before1 = clock();

    for(i=0;i<(SIZE/2);i++)
    {
        arr[i] = 0x00de;
    }
    difference1 = clock() - before1;
    return NULL;
}


void *substitute2(void *operand)
{
    int *arr = (int *)operand;
    int i=0;
    clock_t before2 = clock();

    for(i=(SIZE/2);i<SIZE;i++)
    {
        arr[i] = 0x00de;
    }
    difference2 = clock() - before2;
    return NULL;
}

void single_thread(int *arr);

int main(void)
{
    int arr[SIZE];
    int test[SIZE];
    int msec1, msec2;


    // declare thread variables
    pthread_t thread1;
    pthread_t thread2;

    // create threads
    pthread_create(&thread1, NULL, substitute1, arr);
    pthread_create(&thread2, NULL, substitute2, arr);

    // wait untill the two threads do all their work
    while(arr[SIZE/2 - 1] != 0x00de) {/*printf("arr[%d] = %x\n", SIZE/2 - 1, arr[SIZE/2 -1]);*/};
    while(arr[SIZE-1] != 0x00de) {/*printf("arr[%d] = %x\n", SIZE-1, arr[SIZE-1]);*/};

    // and then join
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    // convert clocks to milliseconds
    msec1 = difference1 * 1000 / CLOCKS_PER_SEC;
    msec2 = difference2 * 1000 / CLOCKS_PER_SEC;

    printf("Multithreading1 : %d ms\n", msec1);
    printf("Mulththreading2 : %d ms\n", msec2);

    // here's the single-threading
    single_thread(test);

    return 0;
}

void single_thread(int *arr) 
{
    int msec = 0, i = 0;

    // declare initial clock
    clock_t single_before = clock();

    for(i=0;i<SIZE;i++)
    {
        arr[i] = 0x00de;
    }

    difference = clock() - single_before;

    // convert clocks to milliseconds
    msec = difference * 1000 / CLOCKS_PER_SEC;
    printf("Singlethreading : %d ms\n", msec);

}
Jun
  • 21
  • 2

2 Answers2

3

Performance improvement in multi-threaded programs comes from distributing the workload between multiple processing units. So your program would have to use the processor enough to justify splitting the workload up. However, all you are doing here is writing data to memory, there is no processing going on, so you are bound by your memory access, as explained here.

mnistic
  • 10,866
  • 2
  • 19
  • 33
2

Hi Multi threading's performance can be measured with large volume of data. With very small volume of data you cannot measure the performance of multithreaded application. The reasons:-

As you said you have 4 processors in your system they are enough to measure the performance of 2 threads in your case. But why it is taking more time than single thread.

  1. To create a thread O/S need to allocation of memory to each thread which take time (even though it is tiny bit.)
  2. When you create multi threads it needs context switching which also take time.
  3. Need to release memory allocated to threads which also take time.

So when you try with small operation with multi threads it's performance will be as same as single thread or even less not suitable at all. So your outcome are preface in this case. To Measure the performance of multithread architecture use large amount of data with complex operation then only you can see the differences.

Now just for understanding see the following scenario. Just consider that sleep is total time requires by a function to complete its task:-

Just do it like below you can see the difference:-

void callme()
{
   printf("In callme()\n");
   sleep(2);
}

void main()
{
    //read the system time here
    callme();
    callme();
    callme();
    callme();
    callme();
    //read the system time here and check how much time it took in a single thread architecture 
    //it will take more than 10 sec
}

Now try with multi threaded architecture:-

void * callme(void *)
{
   printf("In callme()\n");
   sleep(2);
   return NULL; //better use pthread_exit(NULL);
}


void main()
{
    //read the system time here
    pthread_t thread1;
    pthread_t thread2;
    pthread_t thread3;
    pthread_t thread4;
    pthread_t thread5;


    pthread_create(&thread1, NULL, callme, NULL);
    pthread_create(&thread2, NULL, callme, NULL);
    pthread_create(&thread3, NULL, callme, NULL);
    pthread_create(&thread4, NULL, callme, NULL);
    pthread_create(&thread5, NULL, callme, NULL);

        pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);
        pthread_join(thread3, NULL);
        pthread_join(thread4, NULL);
        pthread_join(thread5, NULL);   

      //read the system time here and check how much time it took in a single thread

    //it will take hardly 2.5 to 3 seconds benefit of 7 to 7.5 second than single thread
}

Hope this will help you to understand.

Abhijit Pritam Dutta
  • 5,521
  • 2
  • 11
  • 17
  • Thanks for the comment. But I’m counting the time over ONLY the for loop in my code, so I still can’t make it why this happens. The only possibility I can consider is the memory bandwidth, but then again, when I assign the same task to main thread and subthread there’s a significant difference in execution time. This is really tough – Jun Mar 16 '18 at 00:10
  • That is because of context switching. I already mentioned it. Read about multi threading and context switching you will understand it. – Abhijit Pritam Dutta Mar 16 '18 at 07:31