I have the following mathematical problem:
If making reduction operations over large arrays creates rounding errors.
As example adding more than 100k samples using floats begin to generate errors of 1%
I solved partially using a reduction by using a tree adding by pairs (as it is said in this web for opencl apps:
link)
My code at function "reduction()" works well to add the array elements.
unfortunately the function "reduction_media()" that add pairs and divide by 2 does not works. What is the error?
MODIFIED the code by add array filling again before usage , now it works.
What I have tried:
#include <iostream>
#include <time.h>
#pragma warning(disable:4996) //disable deprecateds
using namespace std;
typedef unsigned char uchar;
time_t start,stop;
void timer(char *title,int size=0)
{
stop=clock();
cout<<title<< " time ="<<(double) (stop-start)/(double) CLOCKS_PER_SEC<< " secs";
if (size)
cout << " = " << 1e-6*size/( (double)(stop-start)/(double)CLOCKS_PER_SEC ) << " Mops/seg" <<endl;
else
cout<<endl;
start=clock();
}
#define SIZE 100000000 //100Meg
float reduction(float *data,int max)
{
while(max>1)
{
data[max]=0.0;max=(max+1)/2;
for (int i=0;i<max;i++)
data[i]+=data[i+max];
}
return data[0];
}
float reduction_media(float *data,int max)
{
while(max>1)
{
data[max]=data[max/2];max=(max+1)/2;
for (int i=0;i<max;i++)
data[i]=(data[i]+data[i+max])/2.0f;
}
return data[0];
}
void main()
{
cout<<"WARNING: run this program in RELEASE mode. Timing is non correct in DEBUG mode"<<endl;
float *data=new float[SIZE+1];
std::fill(data, data+SIZE, 3.14f);
timer("\n fill(data, data+SIZE, 3.14f) ",SIZE);
start=clock();
float sum=0.0f;
for (int i=0;i<SIZE;i++)
sum+=data[i];
sum=sum/(float) SIZE;
timer("\n Standard for() reduction ",SIZE);
cout << "This should be 3.14="<<sum<<endl;
start=clock();
sum=reduction(data,SIZE)/(float) SIZE;
timer("\n Using reduction() function ",SIZE);
cout << "This should be 3.14="<<sum<<endl;
std::fill(data, data+SIZE, 3.14f);
start=clock();
sum=reduction_media(data,SIZE);
timer("\n Using reduction() function ",SIZE);
cout << "This should be 3.14="<<sum<<endl;
delete data;
cout<<"===END==="<<endl;getchar();
}