0

I'm new to c++ as well as multithreading, but I'm working on a program that does quite a few calculations (N = 10,000). As such, I'm trying to speed it up by delegating some of the calculations to new threads. Eventually, I want to be able to write to the file using yet another thread, but I've been running into issues with getting my structs set up with the arrays needed to execute the function that I need to deal with first. I'm worried that the threads I'm using aren't being used properly as well.

My structs are as follows:

struct gstruct {
    double gaussian[10];
    double ret[6][2];
};

struct pstruct {
    double p1[6][2];
    double p2[6][2];
    double ret[2];
};

The threads handling these structs are supposed to call functions which take array arguments. In ParamThread, the first argument is a double[10], and the second argument is a double[6][2]. In OverlapThread, the first two arguments are double[6][2], and the third argument is a double[2].

DWORD WINAPI ParamThread(void *param){
    gstruct* params = (gstruct*)param;
    compute_params(params->gaussian, params->ret);
    return 0;
}

DWORD WINAPI OverlapThread(void *param){
    pstruct* params = (pstruct*)param;
    compute_overlap(params->p1, params->p2, params->ret);
    return 0;
}

On compile, I receive two errors: "incompatible types in assignment of 'double*' to 'double[10]'" and "invalid array assignment" in my main function:

int main()
{
    cout << "Working...\n";

    double **gaussian_array;
    gaussian_array = (double **)malloc(N*sizeof(double *));
    for(int i = 0; i < N; i++){
        gaussian_array[i] = (double *)malloc(10*sizeof(double));
    }
    fstream gaussians;
    gaussians.open("GaussParams", ios::in);
    gaussians.precision(P);

    if (!gaussians){
        cout << "File not found.";
    }
    else {
    //generate the array of gaussians -> [10000][10]
        int i = 0;
        while(i < N) {
            string strNums;
            string Num;
            string strtab[10];
            getline(gaussians, strNums);
            stringstream nums(strNums);
            nums.precision(P);
            for(int j = 0; j < 10; j++){
                getline(nums, strtab[j], ',');
                stringstream dbl(strtab[j]);
                dbl >> gaussian_array[i][j];
            }
        i += 1;
        }
    }
    gaussians.close();
    //Below is the process to generate the overlap file between all gaussians:
    gstruct gs;
    pstruct ps;
    string buffer;
    ofstream overlaps;
    overlaps.open("OverlapMatrix", ios::trunc);
    overlaps.precision(P);
    for(int i = 0; i < N; i++) {
        double r1[6][2];
        compute_params(gaussian_array[i], r1);
        for(int j = 0 ; j < N; j++){
            double r2[6][2];
            double ol[2];
            gs.gaussian = gaussian_array[j]; // >> "incompatible types in assignment..."
            gs.ret = r2; // >> "invalid array assignment"
            ps.p1 = r1;  // >> "invalid array assignment"
            ps.p2 = r2;  // >> "invalid array assignment"
            ps.ret = ol; // >> "invalid array assignment"

            DWORD gthreadID;
            DWORD pthreadID;

            HANDLE pHandle = CreateThread(NULL, 0, ParamThread, new gstruct, 0, &pthreadID);
            WaitForSingleObject(pHandle, INFINITE);
            HANDLE oHandle = CreateThread(NULL, 0, OverlapThread, new pstruct, 0, &gthreadID);
            WaitForSingleObject(oHandle, INFINITE);
            //write to file (omitted for now)
            /*
            overlaps << ol[0] << "," << ol[1];
            if(j < N - 1)
                overlaps << " ";
            else
                overlaps << "\n";
            */
        }
    }
    overlaps.close();
    return 0;
}

I know I'm committing some serious crimes when it comes to both array assignment and multithreading, and I'm missing something that is very conceptually basic. I've tried a few different options for my structs which slowly devolved my code into something that I wasn't understanding at all, which is dangerous. If what I'm doing/assuming with multithreading and structs is so egregiously wrong that I should just scrap this and stick to a program that doesn't use it at all, I would really appreciate hearing that as well.

Any help is greatly appreciated. Thanks!

  • 1
    While an array can be converted ([decayed](https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay)), the reverse is not true. For one thing, a pointer knows where something is, but does not know the size. – user4581301 Mar 02 '21 at 17:22
  • 2
    If you are looking for speed, `gaussian_array = (double **)malloc(N*sizeof(double *));`, and all of the book-keeping that goes with it, is often a horrible way to make a multi-dimensional array, especially for a small array. The array of arrays approach forces the CPU to chase pointers through memory and not be able to load the cache as effectively. Often you're better off making one huge one dimensional array and performing the math to make it look like multiple dimensions. [Here's a simple 2D example](https://stackoverflow.com/a/2076668/4581301). – user4581301 Mar 02 '21 at 17:27
  • 1
    Side note: using a `vector` or a wrapper object makes the pointer-to-array problem go away. – user4581301 Mar 02 '21 at 17:30

0 Answers0