0

Allow a constant string to be globally accessed by various threads calling a function.

I have the following code which chooses a random char from a list of chars (the permitted alphabet) and appends it to form a random word. I am using this for a genetic algorithm but when I am trying to parallelize it to make it faster (homework assignment) but it ends up going slower. After asking my professor and fixing most of the problems, the last detail is that my alphabet doesn't allow multiple threads to read at the same time.

I have tried defining GENES then using #pragma omp threadprivate(GENES) which is the command that my professor said would work.

I tried

const string GENES = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ"
#pragma omp threadprivate(GENES)

Which returns this when compiled.

error: ‘GENES’ declared ‘threadprivate’ after first use

I also tried

string GENES;
#pragma omp threadprivate(GENES)
GENES = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ;

which returns:

error: ‘GENES’ declared ‘threadprivate’ after first use
#pragma omp threadprivate(GENES)
                             ^
error: ‘GENES’ does not name a type
GENES = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ 1234567890, .-;:_!\"#%&/()=?@${[]}";

Finally I tried defining GENES in the threads and passing them as a parameter or hard encoding them into the function. All of these make the program slower.

I expected the program to go faster, but it actually goes slower, from 0.5 sec to 1-3 sec after adding threads. I checked and this is not due to the time in creating the threads.

This should be fixed by making the string accessible by all threads but I can't seem to compile and run any solutions I have found successfully.

  • can you change your string to a char[] ? – OznOg May 26 '19 at 19:57
  • Would have to change a bit of code, but if it works than yes. – Hector Of The Rose May 26 '19 at 20:01
  • If you have only one function that is called by multiple threads then why not declare that as static const variable and since static initialization is thread safe so it should work. – PapaDiHatti May 26 '19 at 20:07
  • 1
    I do not get what is the interest to declare a **const** var private. There is no risk of races for a read-only var, you will use (a bit) more memory, you (slightly) occupy your stack, you need to copy the var when creating the threads and, if you have two threads on the same core, you duplicate identical data in the cache. This is a small string and should not really change performances, but I sincerely do not understand. – Alain Merigot May 26 '19 at 20:52

2 Answers2

1

So I finally got it to compile with #pragma omp threadprivate(GENES) using the following code thanks to a friend:

extern const string GENES;
#pragma omp threadprivate(GENES)
const string GENES = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ";
1

my alphabet doesn't allow multiple threads to read at the same time.

That's not true.

It is perfectly fine to read from a std::string with multiple threads! Since this it is const, no thread can actually write to it1. It is both correct and fast2.

In C++ in general, const loosely implies thread-safe. Keep GENES shared, this is most likely not the reason for your performance issue.

If you aim to figure out your performance issues, I suggest using appropriate performance analysis tools for your platform that are aware of threading / OpenMP. If you want to ask a question on how to improve your program's parallel performance please make sure to

  1. Include a minimal, reproducible example. That doesn't mean to include your entire program. But a minimal version that exhibits the performance issue.
  2. Share your specific measurement results and methodology.
  3. Tell us how you compile the program and the specifications of the system you run it on (CPU & memory)

1: Assuming no evil const_casts

2: Unless you put a mutable global variable on the same cache-line, which seems rather unlikely.

Zulan
  • 21,896
  • 6
  • 49
  • 109
  • Read this in the morning and waited to ask my professor about it before replying. As you mentioned it was not the string, instead it was a problem that was supposedly fixed with the random numbers and pointers. Although I was able to compile the above lines, in the end using `char[]` worked better as mentioned in the comments. Thanks a lot. – Hector Of The Rose May 27 '19 at 21:19