多线程与单线程进程运行时

时间:2018-04-17 19:29:46

标签: c multithreading operating-system

我目前正致力于多线程mergesort计划。 我比较了多线程与单线程之间的不同运行时间。 我得到的平均值为.022279s(多)vs .00249s(单)

我的问题是为什么单线程应用程序比我的多线程更快?

与单线程相比,Isn多线程应该更有效吗?

多线程代码

#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>



void *run(void *parameters); /* threads call this function */
int alength, flength;
int *array_whole;

FILE *input_file;
int *read_file(char *file_name) {
    input_file = fopen("soulfoodinput.txt", "rt"); // open file
    int arraysize = flength;
    char line[80];
    int integer;
    int index = 0;
    int *input = malloc(arraysize * sizeof(int));


    while (fgets(line, 80, input_file) != NULL) 
{
        sscanf(line, "%d", &integer); // read the integer value
        input[index] = integer;
        //printf(line);
        ++index;
        ++alength;
    }
    fclose(input_file); // close the file    
    return input;
}


int read_length(char *file_name) {
    input_file = fopen(file_name, "rt"); // open file
    char line[80];
    int file_length = 0;

    while (fgets(line, 80, input_file) != NULL) {
        file_length += 1;
    }

    return file_length;
}

void merge(int arr[], int left, int middle, int right) //function to sort unsorted array
{  
    int i, j, k;
    //create array partition
    int left_partition = middle - left + 1;
    int right_partition = right - middle;

    int first[left_partition], second[right_partition]; //set up temporary arrays

    //move left side of array to temp array
    for (i = 0; i < left_partition; i++)
    {
        first[i] = arr[left + i];
    }
    //move right side of array to temp array
    for (j = 0; j < right_partition; j++)
    {
        second[j] = arr[middle + 1 + j];
    }

    i = 0;
    j = 0;
    k = left;

    while (i < left_partition && j < right_partition)
    {
        //sort the array into one array
        if (first[i] <= second[j])
        {
            arr[k] = first[i];
            ++i;
        }
        else
        {
            arr[k] = second[j];
            j++;
        }
        k++;
    }

    while (i < left_partition)
    {
        arr[k] = first[i];
        i++;
        k++;
    }

    while (j < right_partition)
    {
        arr[k] = second[j];
        j++;
        k++;
    }
}

void merge_sort(int arr[], int left, int right) //splits array in half, calls self on both halves, then merges the halves
{
    if (left < right)
    {
        int middle = (left + (right-1))/ 2;
        merge_sort(arr, left, middle); //split left half
        merge_sort(arr, middle+1, right); //split right half
        merge(arr, left, middle, right); //merge both halves
    }
}


int main(int argc, char *argv[])
{
    /*WILL CREATES THREAD ID 1, 2, 3 */
    pthread_t thread_id1; // creates first thread id
    pthread_attr_t attr_1; // creates thread attributes
    pthread_t thread_id2; // creates second thread id
    pthread_attr_t attr_2; // second thread attributes
    pthread_t thread_id3; // creates third thread id
    pthread_attr_t attr_3;// third thread attributes

    /* WILL READ IN FILE WITH UNSORTED ARRAY*/
    char *file_name = argv[1];
    flength = read_length(file_name);
    array_whole = read_file(file_name);

  clock_t t;

    int m;
    printf("UNSORTED: ");
    for (m = 0; m < alength; m++) {
        if (m == alength - 1) {
            printf("%d \n", array_whole[m]);
        }
        else {
            printf("%d, ", array_whole[m]);
        }
    }

  t=clock();
    /*WILL CREATE THREAD 1,2,3 */
    char *thread_1 = "first"; // creates first thread
    pthread_attr_init(&attr_1); //finds attributes
    pthread_create(&thread_id1, &attr_1, run, thread_1); // create 1st thread
    char *thread_2 = "second";
    pthread_attr_init(&attr_2);
    pthread_create(&thread_id2, &attr_2, run, thread_2);  // create 2nd thread
    char *thread_3 = "third";
    pthread_attr_init(&attr_3);
    pthread_create(&thread_id3, &attr_2, run, thread_3);  // create 3rd thread

    /*WILL JOIN ALL THE THREADS TOGETHER*/
    pthread_join(thread_id1, NULL); 
    pthread_join(thread_id2, NULL);
    pthread_join(thread_id3, NULL);

  t=clock() - t;
  double time_taken = ((double)t)/CLOCKS_PER_SEC;


    /* WILL PRINT ALL SORTED VALUES */
    int i;
    printf("SORTED: ");
    for (i = 0; i < alength; i++) {
        if (i == alength - 1) {
            printf("%d \n", array_whole[i]);
        }
        else {
            printf("%d, ", array_whole[i]);
        }
    }
  printf("elapsed time = %f seconds to execute \n", time_taken);

    pthread_exit(0);

    return 0;
}


void *run(void *parameters)
{
    int centerspot = alength / 2;
    if (strcmp(parameters, "first") == 0) {
        merge_sort(array_whole, 0, centerspot);
    }

    if (strcmp(parameters, "second") == 0) {
        merge_sort(array_whole, centerspot + 1, alength - 1);
    }

    if (strcmp(parameters, "third") == 0) {
        merge_sort(array_whole, 0, alength - 1);
    }

    pthread_exit(0);
}

单线程代码

#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>



void *run(void *parameters); /* threads call this function */
int alength, flength;
int *array_whole;

FILE *input_file;
int *read_file(char *file_name) {
    input_file = fopen("soulfoodinput.txt", "rt"); // open file
    int arraysize = flength;
    char line[80];
    int integer;
    int index = 0;
    int *input = malloc(arraysize * sizeof(int));


    while (fgets(line, 80, input_file) != NULL) 
{
        sscanf(line, "%d", &integer); // read the integer value
        input[index] = integer;
        //printf(line);
        ++index;
        ++alength;
    }
    fclose(input_file); // close the file    
    return input;
}


int read_length(char *file_name) {
    input_file = fopen(file_name, "rt"); // open file
    char line[80];
    int file_length = 0;

    while (fgets(line, 80, input_file) != NULL) {
        file_length += 1;
    }

    return file_length;
}

void merge(int arr[], int left, int middle, int right) //function to sort unsorted array
{  
    int i, j, k;
    //create array partition
    int left_partition = middle - left + 1;
    int right_partition = right - middle;

    int first[left_partition], second[right_partition]; //set up temporary arrays

    //move left side of array to temp array
    for (i = 0; i < left_partition; i++)
    {
        first[i] = arr[left + i];
    }
    //move right side of array to temp array
    for (j = 0; j < right_partition; j++)
    {
        second[j] = arr[middle + 1 + j];
    }

    i = 0;
    j = 0;
    k = left;

    while (i < left_partition && j < right_partition)
    {
        //sort the array into one array
        if (first[i] <= second[j])
        {
            arr[k] = first[i];
            ++i;
        }
        else
        {
            arr[k] = second[j];
            j++;
        }
        k++;
    }

    while (i < left_partition)
    {
        arr[k] = first[i];
        i++;
        k++;
    }

    while (j < right_partition)
    {
        arr[k] = second[j];
        j++;
        k++;
    }
}

void merge_sort(int arr[], int left, int right) //splits array in half, calls self on both halves, then merges the halves
{
    if (left < right)
    {
        int middle = (left + (right-1))/ 2;
        merge_sort(arr, left, middle); //split left half
        merge_sort(arr, middle+1, right); //split right half
        merge(arr, left, middle, right); //merge both halves
    }
}


int main(int argc, char *argv[])
{
    /*WILL CREATES THREAD ID */
    pthread_t thread_id1; // creates first thread id
    pthread_attr_t attr_1; // creates thread attributes

    /* WILL READ IN FILE WITH UNSORTED ARRAY*/
    char *file_name = argv[1];
    flength = read_length(file_name);
    array_whole = read_file(file_name);

  clock_t t;

    int m;
    printf("UNSORTED: ");
    for (m = 0; m < alength; m++) {
        if (m == alength - 1) {
            printf("%d \n", array_whole[m]);
        }
        else {
            printf("%d, ", array_whole[m]);
        }
    }

  t=clock();
    /*WILL CREATE THREAD 1,2,3 */
    char *thread_1 = "first"; // creates first thread
    pthread_attr_init(&attr_1); //finds attributes
    pthread_create(&thread_id1, &attr_1, run, thread_1); // create 1st thread

    /*WILL JOIN ALL THE THREADS TOGETHER*/
    pthread_join(thread_id1, NULL); 


  t=clock() - t;
  double time_taken = ((double)t)/CLOCKS_PER_SEC;


    /* WILL PRINT ALL SORTED VALUES */
    int i;
    printf("SORTED: ");
    for (i = 0; i < alength; i++) {
        if (i == alength - 1) {
            printf("%d \n", array_whole[i]);
        }
        else {
            printf("%d, ", array_whole[i]);
        }
    }
  printf("elapsed time = %f seconds to execute \n", time_taken);

    pthread_exit(0);

    return 0;
}


void *run(void *parameters)
{
    int centerspot = alength / 2;

        merge_sort(array_whole, 0, centerspot);

        merge_sort(array_whole, centerspot + 1, alength - 1);

        merge_sort(array_whole, 0, alength - 1);


    pthread_exit(0);
}

2 个答案:

答案 0 :(得分:2)

多线程的性能可以用大量数据来衡量。使用非常少量的数据,您无法测量多线程应用程序的性能。原因: -

  

1.要创建一个线程O / S需要为每个线程分配内存需要花费时间(即使它很小)。

     

2.当您创建多线程时,它需要上下文切换,这也需要时间。

     

3.需要释放分配给线程的内存,这也需要时间。

     

4.取决于您机器中的处理器数量和总内存(RAM)

因此,当您尝试使用多线程进行小操作时,其性能将与单线程相同甚至更低。所以在这种情况下你的结果是完美的。要测量多线程架构的性能,请使用大量数据并进行复杂操作,然后才能看到差异。

答案 1 :(得分:1)

线程需要时间来设置和启动。要完成的工作量越大,多线程减少完成任务所花费的总时间的可能性就越大。

在你的例子中,我猜测文件 soulfoodinput.txt 不是很大,所以我建议把它放大,如果可能的话它应该包含数百甚至数千行。然后看看多线程代码是否比单线程运行得快。