#how does multitreading memory work in c++?

123 messages · Page 1 of 1 (latest)

real fern
severe sageBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.

steel orbit
#

your question is way too broad

quartz parcel
# real fern the code I got I know it is terrible

first you need a single-threaded solution, then you need to think how to distribute the work into N threads, then you gotta learn the std::thread syntax, and then implement a multithreaded solution

#

!asan

severe sageBOT
# quartz parcel !asan
How to Use Sanitizers

Sanitizers are tools which generate additional code in your program that can catch many common programming mistakes, such as:

General Advice

Not all sanitizers can be combined, but when they can, use e.g.:
-fsanitize=address,undefined to combine them. Always compile with debug info to get line numbers, variable names, etc.

MSVC
Sample Program
int main(void) {
    int x;
    return x;
}
`-fsanitize=memory -g` Output

SUMMARY: MemorySanitizer: use-of-uninitialized-value /tmp/test.cpp:3:5 in main
Exiting

(3:5 is the line and column of return)

steel orbit
#

also,
when you work with multi threading, global variables are shit (in general they are shit). Try to avoid them.
smallchange is also terribly implemented I think, everytime you call it, it creates

    std::random_device rd;
    std::mt19937 gen(rd());

this should be not inside the function body imo, and probably be thread_local

#

and some functions are static for whatever reason?

quartz parcel
#

"are shit" here means, they cause race conditions, that corrupt your memory and cause crashes

real fern
real fern
real fern
#

Global variables

quartz parcel
steel orbit
#

create structs, class

steel orbit
#

and the mersenne twister is a pseudo random number generator

#

;compile cpp

#include <iostream>
#include <random>

std::random_device rd;
std::mt19937 gen(rd());

int foo () {
    std::uniform_int_distribution<> distrib(0, 15);
    return distrib(gen);
}

int main() {
    for (int i = 0; i < 5; i++)
    {
        std::cout << foo() << std::endl;
    }

    return 0;
}
wanton lagoonBOT
#
Program Output
15
3
8
15
1
steel orbit
#

so what your code is actually doing, is recreating a mersenne twister in every call as well as the random device

#

some stuff in your code is flawed, i.e. reversevariable1 which exists both as a global variable and as a local variable

#

prime example of why not to use globals

#

int reversevariable1 = randomIndex1; in your first function is doing nothing

#

;compile cpp

#include <iostream>

int x = 1;

void foo () {
    int x = 2;
}

int main() {
    foo();
    
    std::cout << x;
    return 0;
}
wanton lagoonBOT
#
Program Output
1
steel orbit
#

float _ = also wtf is this

#

I mean you probably think why im hating on this when all you asked about was multithreading

#

but adding multi threading to a program where the execution flow is difficult to understand is just a really bad idea

real fern
steel orbit
#

you are working on it.

#

That are enough people

real fern
#

But the _ is just a placeholder because I couldn’t read that long lines and as an inbetween step but I should probably put that together

steel orbit
#

ik but still, anyway that's not an issue

#

reversevariable1 is though

real fern
steel orbit
#
#include <iostream>

float foo() {
        float sum;
        sum += 2;
        return sum;
}

int main() {
        std::cout << foo();
        return 0;
}

also this code adds to an uninitialized value which is also bad..and i.e. valgrind will fire

real fern
#

I don’t understand

steel orbit
steel orbit
# real fern I don’t understand

on line 87 you have a sum float and then you add something to the float

    float sum;
    int numVertices = argGraph.size(); 
    for (int index = 0; index < numVertices; ++index) {
        std::vector<int> shortestDistances = dijkstra(argGraph, index, argpositions);
        for (int i = 0; i < numVertices; ++i) {
            sum += argweights[i] * (shortestDistances[i] - Mydistance(i, index, argpositions));
        }
    }
    return sum;

sum is uninitialized

#

a few lines down you do it correct, float sum = 0.0;

steel orbit
#

thats basically what you are doing, just in small

#

you need to drop the int which creates a new variable

real fern
#

Ahh

#

I see

steel orbit
#

also this global variable is useless
std::vector<int> weights;

#

it's doing nothing

#

also you are already creating position in main... just pass it as a parameter into renderingThread

#

vectorOfset is also not used

#

so, id say clean it up and remove all global variables and then try to add multithreading

real fern
real fern
#

would it be a good idea to put the global variables in a class and add small change and u to that class?

quartz parcel
#

call it struct graphState

#

or something

real fern
#

what is a struct exactly? (what problem does it solve?)

quartz parcel
real fern
#

why did they come up with it

quartz parcel
#

imagine implementing it manually instead

real fern
quartz parcel
#

but the fields are pubic by default

steel orbit
#

structs are usually for pod (plain old data) and classes in c++ enable all kind of OOP stuff like inheritance, which is not really possible with structs

#

imagine structs like a package, and classes could be a mailmen.
Package has a width, height and length (3d object) and probably a weight. Thats all which you need to describe a package so its POD.

#

A mailmen has methods and member variables like a store which holds all the packages he has to deliver

real fern
#

could you also add functions to structs?

real fern
steel orbit
real fern
#
#include <iostream>
#include <random>

std::random_device rd;
std::mt19937 gen(rd());

float foo () {
    std::uniform_int_distribution<> distrib(0, 1);
    return distrib(gen);
}

int main() {
    for (int i = 0; i < 5; i++)
    {
        std::cout << foo() << std::endl;
    }

    return 0;
}
#

hm

#

how does bot work

#

;compile cpp

#include <iostream>
#include <random>

std::random_device rd;
std::mt19937 gen(rd());

float foo () {
    std::uniform_int_distribution<> distrib(0, 1);
    return distrib(gen);
}

int main() {
    for (int i = 0; i < 5; i++)
    {
        std::cout << foo() << std::endl;
    }

    return 0;
}```
wanton lagoonBOT
#
Program Output
0
1
1
0
0
real fern
#

hm

real fern
#

;compile cpp

// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    // Using srand() with time(0) to change
    // the random values everytime
    srand(time(0));
 
    // Loop to check that we get different values
    // on every iteration
    for (int i = 0; i < 10; i++) {
 
        // Typecasting the random value
        // obtained into a double and
        // then dividing it with RAND_MAX
        cout << ((double)rand()) / RAND_MAX << endl;
    }
 
    return 0;
}```
wanton lagoonBOT
#
Program Output
0.483602
0.131687
0.104625
0.746465
0.831092
0.715225
0.826825
0.768559
0.61094
0.350964
real fern
#

;compile cpp
// C++ code to implement the approach

#include <bits/stdc++.h>
using namespace std;

int main()
{
// Using srand() with time(0) to change
// the random values everytime
srand(time(0));

// Loop to check that we get different values
// on every iteration
for (int i = 0; i < 10; i++) {

    // Typecasting the random value
    // obtained into a double and
    // then dividing it with RAND_MAX
    cout << ((double)rand()) / RAND_MAX << endl;
}

return 0;

}

wanton lagoonBOT
#
Critical error:

You must attach a code-block containing code to your message or quote a message that has one.

real fern
#

;compile cpp
// C++ code to implement the approach

#include <bits/stdc++.h>
using namespace std;

int main()
{
// Using srand() with time(0) to change
// the random values everytime
srand(time(0));

// Loop to check that we get different values
// on every iteration
for (int i = 0; i < 10; i++) {

    // Typecasting the random value
    // obtained into a double and
    // then dividing it with RAND_MAX
    cout << ((double)rand()) / RAND_MAX << endl;
}

return 0;

}

wanton lagoonBOT
#
Critical error:

You must attach a code-block containing code to your message or quote a message that has one.

real fern
#

;compile cpp

// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    // Using srand() with time(0) to change
    // the random values everytime
    srand(time(0));
    float randnumb = (double)rand()) / RAND_MAX;
    cout << randnumb;
 
    return 0;
}```
wanton lagoonBOT
#
Compiler Output
<source>: In function 'int main()':
<source>:11:36: error: expected ',' or ';' before ')' token
   11 |     float randnumb = (double)rand()) / RAND_MAX;
      |                                    ^
Build failed
real fern
#

;compile cpp

// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
int main()
{
    // Using srand() with time(0) to change
    // the random values everytime
    srand(time(0));
    float randnumb = (double)rand() / RAND_MAX;
    cout << randnumb;
 
    return 0;
}```
wanton lagoonBOT
#
Program Output
0.562364
steel orbit
#

Can you please not go 5 steps back ?xd

#

Don’t use srand, namespace std, bits/stdc++, c style casts

real fern
#

Why?

split pilot
# real fern Why?
  1. srand / rand, are fairly low quality random numbers, and often used wrongly. C++ random number facilities are more porfrull
  2. using namespace std; universally considered bad practisch
  3. #include <bits/stdc++.h> non portable and non standard header that includes everything what is also undesirable
  4. c style casts will cast whatever, C++ casts are much more restrictive what is beneficial
#

and to circle back to why structs / classes. They bundle variables and or functionality togheter in a logicall group what makes programming much easier, imagine if you only had loose variables, it would be absolutly miserable

real fern
#

how should I than do random numbers

steel orbit
#

You were generating random numbers fine before

#

Just the initialization should have been outside of the loop

real fern
#

what do you mean with initialise before the loop?

steel orbit
real fern
#

does it give a different value everytime you run it?

steel orbit
#

Bro you ran the code yourself…

steel orbit
real fern
#

;compile cpp

#include <iostream>
#include <random>

std::random_device rd;
std::mt19937 gen(rd());

float foo () {
    std::uniform_float_distribution<> distrib(0, 1);
    return distrib(gen);
}

int main() {
    for (int i = 0; i < 5; i++)
    {
        std::cout << foo() << std::endl;
    }

    return 0;
}```
wanton lagoonBOT
#
Compiler Output
<source>: In function 'float foo()':
<source>:8:10: error: 'uniform_float_distribution' is not a member of 'std'; did you mean 'uniform_real_distribution'?
    8 |     std::uniform_float_distribution<> distrib(0, 1);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~
      |          uniform_real_distribution
<source>:8:37: error: expected primary-expression before '>' token
    8 |     std::uniform_float_distribution<> distrib(0, 1);
      |                                     ^
<source>:8:39: error: 'distrib' was not declared in this scope
    8 |     std::uniform_float_distribution<> distrib(0, 1);
      |                                       ^~~~~~~
Build failed
steel orbit
#

Because different values and random values ain’t the same

real fern
#

because of pseudorandomness or because it always has the same seed?

steel orbit
#

What

real fern
#

what did you than mean with that different values and random values are not the same?

steel orbit
#

If you always want different values just count up. If you want random values use a random number generator

#

In general you seed a PRNG once and then you simply reuse the seeded PRNG. The code that you first shared here reseeded it every time and thus causes issues with the generated sequence which might no longer be statistically be random

real fern
#

why would reseeding it every time cause it not to be random?

split pilot
#

it's not uncommon for the first few numbers after seeding to be rather low quality for example

real fern
#

I am confused

split pilot
#

about what exactly?

steel orbit
#

https://stackoverflow.com/questions/7320840/good-idea-to-seed-a-rng-each-time-you-use-it
This has a good example I think,

For instance, consider a PRNG which always returns the seed value itself as the first number in the sequence, but which is perfectly uniform over its range. This constitutes a great PRNG, as long as you don't use the first number. However, if you reseed it before every use, say to an incrementing counter value, you have no randomness at all!

#

and in most apps you are fine with initializing your mersenne twister once with one seed, and then you keep using that. You get enough good random numbers

#

If you want something secure you will need a true physical rng but at that point we probably wouldnt even have that discussion 😄

severe sageBOT
#

This question is being automatically marked as stale.
If your question has been answered, run !solved.
If your question is not answered feel free to bump the post or re-ask.
Take a look at !howto ask for tips on improving your question.

real fern
#

h,

real fern
real fern
#

there seems to be a problem with the arguments I am putting in my tread but I can't figger out