2

I currently have a code which works well, but I am learning C++, and hence would like to rid myself of any newbie mistakes. Basically the code is

vector<vector<float>> gAbs; void functionThatAddsEntryTogAbs(){ ... gAbs.pushback(value); } int main(){ thread thread1 = thread(functionThatAddsEntryTogAbs,args); thread thread2 = thread(functionThatAddsEntryTogAbs,args); thread1.join(); thread2.join(); std::sort(gAbs.begin(),gAbs.end()); writeDataToFile(gAbs,"filename.dat"); } 

For instance I remember learning that there are only a few instances where global variables are the right choice. My initial thought was just to have the threads write to the file, but then I cannot guarantee that the data is sorted (which I need), which is my I use std::sort. Are there any suggestions of how to improve this, and what are some alternatives that the more experiences programmers would use instead?

The code needs to be as fast as possible.

Thanks in advance

10
  • 2
    In general having two threads add entries to a global vector is not my idea of how to write fast code. In order to make access to the vector thread safe you will have to lock the vector which will slow things down a lot. Would it not be possible to have each thread write to it's own vector (global if necessary) and then combine the vectors at the end before sorting the combined vector. Commented Jun 14, 2022 at 7:02
  • 1
    It's pretty much always a bad idea to have concurrent writes in your code, and if I remember correctly, std::vector isn't thread-safe. If your function functionThatAddsEntryTogAbs does more than just adding an entry (computes something before), I would advise you to take a look at Mutexes. These are basically locks, and you could simply acquire it just before the insertion, and unlock it afterwards, to still allow the computation to be done in multiple threads Commented Jun 14, 2022 at 7:02
  • Thank you @john, that seems to be a solution that is less dirty – I assumed my solution would be faster because I avoid the extra step of joining all the vectors together, but I'll give this a try. Commented Jun 14, 2022 at 7:07
  • I'll have a look at Mutexes, thanks @Ladislus Commented Jun 14, 2022 at 7:08
  • Note that if your code dosen't do anything too computationally intensive, adding a mutex could be slower than a sequential program, as you would have the overhead of creating/launching the threads, that would have to wait for others to finish anyway. @john 's answers seems a lot better, doing it in a divide-to-conquer manner, and it would also remove the global variables, that are (almost) alway evil Commented Jun 14, 2022 at 7:13

1 Answer 1

1

You can access and modify global resources, including containers from different threads, but you have to protect them from doing that at the same time. Some exceptions are: no modifications are possible, the container itself is not changed and the threads are working on separate entries.

In your code, entries are added to the container, so you need mutexes, but by doing that your parallel code probably doesn't gain you much in speed. A better way could be to know how many entries need to be added, add empty entries (just initialize) and then assign ranges to the threads, so they can fill in the entries.

Sign up to request clarification or add additional context in comments.

4 Comments

Yeah I always know exactly how many points there are, so that would def work. Would you suggest using float[][] instead of vector<vector<>>? The data short be sorted automatically using your suggestion, in which case there's no benefit of using vector, right?
@PeterDanielJohannsen irregardless of storage used, unless operations are atomic or were fenced by inter-thread locks, the result would be UB.
@PeterDanielJohannsen vectors and arrays don't sort automatically. If you don't need dynamic memory, arrays will be faster. I prefer std::array<std::array<type, size1>, size2> over [size1][size2] because you get all the benefits of a container.
@PeterDanielJohannsen also, there's no reason to assume that just for filling a container, threads will increase speed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.