Could you please some one help me to identify the issues in the following code.
Background: The test code adds two arrays, input1 & input2 and stores the results in output, using 4-threads.
The problem was one of the thread not able to do correctly, output buffer shows "0" randomly for one of the threads. Any help highly appreciated.
#include<iostream>
#include<pthread.h>
#include<unistd.h>
using namespace std;
int input1[1000], input2[1000], output[1000];
void* Addition(void* offset) {
int *local_offset = (int*)offset;
for(int i = ((*local_offset) * 250); i < ((*local_offset)+1)*250; ++i) {
output[i] = input1[i] + input2[i];
}
pthread_exit(0);
}
int main() {
pthread_t thread_id[4];
void* status;
fill_n(input1, 1000, 3); // input1, fill the buffer with 3
fill_n(input2, 1000, 4); // input2, fill the buffer with 4
fill_n(output, 1000, 0); // output, fill the buffer with 0
// create 4 thread with load of 250items
for(int i = 0; i < 4; ++i) {
int result = pthread_create(&thread_id[i], NULL, Addition, &i);
if(result) cout << "Thread creation failed" << endl;
}
// join the 4-threads
for(int i = 0; i < 4; ++i) {
int result = pthread_join(thread_id[i], &status);
if(result) cout << "Join failed " << i << endl;
}
// print output buffer, the output buffer not updated properly,
// noticed"0" for 1 & 2 thread randomly
for(int i =0; i < 1000; ++i)
cout << i << " " << output[i] << endl;
pthread_exit(NULL);
}
I have found the root cause of the issue...
The "&i" gives unknown result because "i" memory will be overwritten by ++i and thread_id[0] get different value by the time the thread created... so you should have a dedicated memory so that no overwriting will happen by ++i;
&i is the problem...
int result = pthread_create(&thread_id[i], NULL, Addition, &i);
To solve, replace with &shared_data[i] ....
int result = pthread_create(&thread_id[i], NULL, Addition, &shared_data[i]);
The shared_data is an array of 4 elements.. like this
int shared_data[4] = {0,1,2,3};
Related
My Compiler gives runtime error when I initialize the float array in Veccreator function. I am here posting just a sample of what my code looks like.
#include<iostream>
using namespace std;
#define SIZE 1000
class Vector
{
private:
float vecarray[SIZE];
public:
void VecCreator(int dimension)
{
vecarray[SIZE]= { 0 };
cout << "Enter " << dimension << " digits" << endl;
for (int i = 0; i < dimension; i++)
{
cin >> vecarray[i];
}
}
};
int main(void) {
Vector obh;
obh.VecCreator(2);
}
But it works fine with this:`
#include<iostream>
using namespace std;
#define SIZE 1000
class Vector
{
private:
float vecarray[SIZE]= {0};
public:
void VecCreator(int dimension)
{
cout << "Enter " << dimension << " digits" << endl;
for (int i = 0; i < dimension; i++)
{
cin >> vecarray[i];
}
}
};
int main(void) {
Vector obh;
obh.VecCreator(2);
}
Please tell me why the first code is giving error.
Look at the second answer here:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/14e7318e-6fff-4d68-a823-9cbe7b7bc20a/debugging-runtime-check-failure-2-stack-around-the-variable-loggerthread-was-corrupted?forum=vcgeneral
why not do it like here below? i mean if you want to put values in there, why initially put 0 in there?
private:
float vecarray[SIZE];
public:
void VecCreator(int dimension)
{
cout << "Enter " << dimension << " digits" << endl;
for (int i = 0; i < dimension; i++)
{
cin >> vecarray[i];
}
}
I'm trying to run this code in VS 2015 c++, but I have this problem: while getting the correct answer, I also get the error C++ Console Application1.exe has triggered a breakpoint. My task is to randomly choose 10 numbers between 1 and 50, show these numbers and sort them by odd and even numbers. Thanks in advance.
#include<iostream>
#include<ctime>
using namespace std;
void main() {
const int size = 10;
srand(time(NULL));
int arr[size], odd = 0, even = 0;
for (int i = 0; i < size; i++)
{
arr[i] = rand() % 50 + 1;
cout << arr[i] << '\t';
}
cout << endl;
int *arrOdd = new int[odd];
int *arrEven = new int[even];
for (int i = 0; i < size; i++)
{
if (arr[i] % 2 == 0) {
arrEven[even] = arr[i];
even++;
}
else
{
arrOdd[odd] = arr[i];
odd++;
}
}
int a = 0, b = 0;
for (int i = 0; i < size; i++)
if (arr[i] % 2 == 0) {
cout << "arrEven = " << arrEven[a] << endl;
a++;
}
else
{
cout << "arrOdd = " << arrOdd[b] << endl;
b++;
}
system("pause");
}
int arr[size], odd = 0, even = 0;
//odd's and event's dont change
//...
int *arrOdd = new int[odd];
int *arrEven = new int[even];
So you are trying to allocate arrays with 0 length
i have to find the max and min value in array of random numbers... here is my code:
#include<iostream>
using namespace std;
void populateArray();
int findMin();
int findMax();
int computeTotal();
int arr[50];
int small, big;
void main()
{
big = small = arr[0];
populateArray();
findMin();
findMax();
computeTotal();
system("pause");
}
void populateArray()
{
for (int i = 0; i < 48; i++)
{
arr[i] = rand() % 1000;
cout << arr[i] << " ";
}
cout << endl;
}
int findMin()
{
for (int i = 0; i < 48; i++)
{
if (arr[i] < small)
{
small = arr[i];
}
cout << "The smallest number is " << small << endl;
return 0;
}
}
int findMax()
{
for (int i = 0; i < 48; i++)
{
if (arr[i] > big)
{
big = arr[i];
}
}
cout << "The biggest number is " << big << endl;
return 0;
}
int computeTotal()
{
int sum = 0;
sum = big + small;
cout << "Total= " << sum << endl;
return 0;
}
But the problem is that it does not display the minimum and maximum value from the array... it displays minimum value 0 and max 995 which are not included even in the array..
any help??
I have tried to use Magick++. I tried to load an Image with it but it fails
void mPDF::addImage(std::string path, unsigned int x, unsigned int y)
{
Magick::InitializeMagick("C:\\CommonFiles\\GraphicsMagick\\");
//with or without the ending two \\ same results
Magick::Image img;
try
{
img.read("c:\\temp\\Moon.jpg");
}
catch (Magick::ErrorBlob p)
{
std::cout << "Folder: " << path << std::endl;
std::cout << p.what() << std::endl;
system("pause");
exit(1);
}
Magick::Geometry tmp = img.size();
for (int i = 0; i < tmp.height(); i++)
{
for (int j = 0; j < tmp.width(); j++)
{
Magick::Color col = img.pixelColor(i, j);
this->p.setLineColor(col.redQuantum(), col.greenQuantum(), col.blueQuantum());
this->p.drawLine(x + j, y - i, x + j, y - i);
}
}
}
it throws an exception that he can't load the file. It says : unable to open Image '³.0': No such File or directory. In Magick++ Documentation it is written like I used it.
Can someone help me?
The below test case runs out of memory on 32 bit machines (throwing std::bad_alloc) in the loop following the "post MT section" message when OpenMP is used, however, if the #pragmas for OpenMP are commented out, the code runs through to completion fine, so it appears that when the memory is allocated in parallel threads, it does not free correctly and thus we run out of memory.
Question is whether there is something wrong with the memory allocation and deletion code below or is this a bug in gcc v4.2.2 or OpenMP? I also tried gcc v4.3 and got same failure.
int main(int argc, char** argv)
{
std::cout << "start " << std::endl;
{
std::vector<std::vector<int*> > nts(100);
#pragma omp parallel
{
#pragma omp for
for(int begin = 0; begin < int(nts.size()); ++begin) {
for(int i = 0; i < 1000000; ++i) {
nts[begin].push_back(new int(5));
}
}
}
std::cout << " pre delete " << std::endl;
for(int begin = 0; begin < int(nts.size()); ++begin) {
for(int j = 0; j < nts[begin].size(); ++j) {
delete nts[begin][j];
}
}
}
std::cout << "post MT section" << std::endl;
{
std::vector<std::vector<int*> > nts(100);
int begin, i;
try {
for(begin = 0; begin < int(nts.size()); ++begin) {
for(i = 0; i < 2000000; ++i) {
nts[begin].push_back(new int(5));
}
}
} catch (std::bad_alloc &e) {
std::cout << e.what() << std::endl;
std::cout << "begin: " << begin << " i: " << i << std::endl;
throw;
}
std::cout << "pre delete 1" << std::endl;
for(int begin = 0; begin < int(nts.size()); ++begin) {
for(int j = 0; j < nts[begin].size(); ++j) {
delete nts[begin][j];
}
}
}
std::cout << "end of prog" << std::endl;
char c;
std::cin >> c;
return 0;
}
Changing the first OpenMP loop from 1000000 to 2000000 will cause the same error. This indicates that the out of memory problem is with OpenMP stack limit.
Try setting the OpenMP stack limit to unlimit in bash with
ulimit -s unlimited
You can also change the OpenMP environment variable OMP_STACKSIZE and setting it to 100MB or more.
UPDATE 1: I change the first loop to
{
std::vector<std::vector<int*> > nts(100);
#pragma omp for schedule(static) ordered
for(int begin = 0; begin < int(nts.size()); ++begin) {
for(int i = 0; i < 2000000; ++i) {
nts[begin].push_back(new int(5));
}
}
std::cout << " pre delete " << std::endl;
for(int begin = 0; begin < int(nts.size()); ++begin) {
for(int j = 0; j < nts[begin].size(); ++j) {
delete nts[begin][j]
}
}
}
Then, I get a memory error at i=1574803 on the Main thread.
UPDATE 2: If you are using the Intel compiler, you can add the following to the top of your code and it will solve the problem (providing you have enough memory for the extra overhead).
std::cout << "Previous stack size " << kmp_get_stacksize_s() << std::endl;
kmp_set_stacksize_s(1000000000);
std::cout << "Now stack size " << kmp_get_stacksize_s() << std::endl;
UPDATE 3: For completeness, like mentioned by another member, if you are performing some numerical computation, it is best to preallocate everything in a single new float[1000000] instead of using OpenMP to do 1000000 allocations. This applies to allocating objects as well.
I found this issue elsewhere seen without OpenMP but just using pthreads. The extra memory consumption when multi-threaded appears to be typical behavior for the standard memory allocator. By switching to the Hoard allocator the extra memory consumption goes away.
Why are you using int* as the inner vector member? That's very wasteful - you have 4 bytes (sizeof(int), strictly) of data and 2-3 times more again of heap control structure for every vector entry. Try this just using vector<int> and see if it runs better.
I'm not an OpenMP expert but this usage seems weird in its asymmetry - you fill the vectors in parallel section and clear them in non-parallel code. Cannot tell you whether that's wrong, but it 'feels' wrong.