无法通过使霍夫曼算法平行

时间:2016-06-28 12:09:56

标签: multithreading algorithm performance parallel-processing synchronization

我正在尝试实现huffman'a压缩算法。现在我正在研究构建序列表的算法部分。 我们的想法是减少每个字母在文本中出现的次数。我的案例中的文本由一个从文件中读取的字符串表示。我想要做的是使字母的计数平行。我给每个帖子提供相同数量的字母。不幸的是我没有得到任何加速。我不知道可能是什么原因。我使用pthread_spinlock但是使用它应该没有问题,因为数组很小。 参见:

#include <string>
#include <streambuf>
#include <vector>
#include <pthread.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <fstream>
#include <memory>
#include <errno.h>
#include <time.h>

using namespace std;

void parse_arguments(int argc, char* const* const argv, bool& random_edges, int& vertex_count, int& threads_count, char* &input_file, char* &output_file, bool& enable_logging);

pthread_t * threads; 
bool* used_threads;
int used_threads_count;
pthread_spinlock_t lock;
struct dfs_args *thread_args; 
int threads_count;

struct params 
{
   std::string text;
   unsigned long long offset;
   unsigned long long length;
};

const int NUM_LETTERS = 28;
unsigned long long arr[NUM_LETTERS];

void *parallel_huffman(void* args)
{
   unsigned long long arr_local[NUM_LETTERS];
   memset(arr_local, 0, sizeof(arr_local)); 

   struct params* params = (struct params*)args;  
   unsigned long long start = params->offset;
   unsigned long long length = params->length;
   const string text = params->text;

   for (unsigned long long i = start; i < (start + length) && i < (long long)text.size(); ++i)
   {
      if(text[i] >= 'a' && text[i] <= 'z')
      {
         int letter_offset = text[i] - 'a';
         arr_local[letter_offset]++; 
      }

      if(text[i] >= 'A' && text[i] <= 'Z')
      {
         int letter_offset = text[i] - 'A';
         arr_local[letter_offset]++;  
      }
   } 

   pthread_spin_lock(&lock);
      for( int i = 0; i < NUM_LETTERS; ++i)
      {
         arr[i] += arr_local[i];
      } 
   pthread_spin_unlock(&lock);
}

int main(int argc, char* argv[])
{
   double time_spent;
   clock_t begin, end;
   begin = clock();

   threads_count = 0;
   int cur_threads, vertex_count; 
   char* input_file = NULL, *output_file = NULL;
   bool random_edges = false, enable_logging = true;;

   memset(arr, 0, sizeof(arr)); 

   vector<pthread_t> threads;
   vector<params> parameters;
   string text;

   int ret = pthread_spin_init(&lock, PTHREAD_PROCESS_SHARED);
   if (ret != 0)
   {
      printf("Failed to init spin lock errno = %d\n", errno);
      return -1;
   } 

   parse_arguments(argc, argv, random_edges, vertex_count, threads_count, input_file, output_file, enable_logging);

   ifstream input(input_file);

   input.seekg(0, ios::end); 
   text.reserve(input.tellg());
   input.seekg(0, ios::beg);

   text.assign((istreambuf_iterator<char>(input)), istreambuf_iterator<char>());
   //cout << text << endl;
   input.close();

if (threads_count > 1) {
   threads.reserve(threads_count);
   parameters.reserve(threads_count);

   unsigned long long len = text.size() / threads_count;

   pthread_t thread;
   struct params param;
   unsigned long long i;
   for (i = 0; i < threads_count; ++i)
   {
      struct params param;
      param.text = text;
      param.offset = i*len;
      param.length = len;

      parameters.push_back(param);
      threads.push_back(thread); 
   } 

   long long last = parameters.size();
   long long text_size = text.size(); 
   parameters[last-1].length = text_size - parameters[last-1].offset;   

   for (int i = 0; i < threads_count; ++i)
   {
       if (enable_logging) 
          printf("Starting thread number %d\n", i);
       if( pthread_create(&threads[i], NULL, parallel_huffman, &parameters[i]) )
       {
          printf("Failed to create thread");      
          break;
       } 
   }
} else {
   struct params param;
   param.text = text; 
   param.offset = 0;
   param.length = text.size();
   parallel_huffman(&param);
}
   for (int i = 0; i < threads_count; ++i)
   {
      if (enable_logging)
         printf("Awaiting thread number %d\n", i);
      pthread_join(threads[i], NULL);
   }
   for( int i = 0; i < NUM_LETTERS; ++i)
   {
      if (enable_logging)
         printf("%c %llu\n", char('A' + i), arr[i]);
   }  

   end = clock();
   time_spent = (double)(end - begin) / CLOCKS_PER_SEC;

   if (enable_logging) 
      printf("Total execution time of the program -> %f\n", time_spent);
   return 0;
} 

void parse_arguments(int argc, char* const* const argv, bool& random_edges, int& vertex_count, int& threads_count, char* &input_file, char* &output_file, bool& enable_logging)
{
   for (int i = 0; i < argc; ++i) 
   {
      if (0 == strcmp("-n", argv[i]) )
      {
         vertex_count = atoi(argv[i+1]);
         random_edges = true;
      } else if (0 == strcmp("-t", argv[i]) )
      {
         threads_count = atoi(argv[i+1]);
      } else if (0 == strcmp("-f", argv[i]) )
      {
         input_file = argv[i+1]; 
      } else if (0 == strcmp("-o", argv[i]) )
      {
         output_file = argv[i+1];
      } else if (0 == strcmp("-q", argv[i]) )
      {
         enable_logging = false;
      } 
   }
} 

0 个答案:

没有答案