April 01, 2003
This sounds like a more like a DBMS or multi processing issue than mere 3D array.

Any possibility that your 3D array could be sparse array? i.e., not all of the elements are used?

Are you able to break the algorithm into multiple threads working on 2D to work out?

Do you have a computer that really have > 1GB of physical memory? Wow...
otherwise the swap disk takes over and you might as well implement
the algorithm different way.

"Jens Friese" <j.friese@highfisch.de> wrote in message news:3E8404A3.2000108@highfisch.de...
> Hi everybody,
>
> I hardly dare to say that I have no idea
> what pointers are. I just have to create
> this three-dimensional array during runtime
> because it uses up to 800 mb (!) of memory.
> Don't tell me that's too much - I do really need it ;)
> Someone told me, to allocate memory this way -
> and it works fine for me...
>
> Can you tell me an equally easy method to do so
> in a better way? I would be happy if you could
> tell me about this destructor thing too.



April 12, 2003
In article <3E8318B4.20307@highfisch.de>, Jens Friese says...
>
>Hi,
>
>I cannot figure out how to delete this array:
>
> 
>float ***xbuffer,***ybuffer,***zbuffer;

This probably won't help, but I had a lot of fun doing it so.. and sorry about the long post. A good portion of it is conditionally compiled.

Richard

#if 0
xbuffer = new float**[4];
ybuffer = new float**[4];
zbuffer = new float**[4];
for (i=0;i<4;i++) {
xbuffer[i] = new float*[hsize[i]];
ybuffer[i] = new float*[hsize[i]];
zbuffer[i] = new float*[hsize[i]];
for (j=0;j<hsize[i];j++) {
xbuffer[i][j] = new float[vsize[i]];
ybuffer[i][j] = new float[vsize[i]];
zbuffer[i][j] = new float[vsize[i]];
}
}
#endif

//#define OUTPUTTEST
// above macro enables an output test so that this lib can be verified.
// use carefully with CAPACITYTEST or much results displayed..
//#define TESTING
// above macro enables a non template version of the lib to be tested
#define CAPACITYTEST
// above macro allows speed and exception testing
// use carefully with OUTPUTTEST or much results displayed..

#include <deque>
#include <algorithm>

#if defined (OUTPUTTEST) || defined (CAPACITYTEST)
# include <iostream>
#endif

namespace detail {

class Buffer {
public:
Buffer(std::size_t size) throw (std::bad_alloc) :
bound(size), array(0)
{
// gen bad_alloc on fail
array = new unsigned char[bound];
if (array == 0)
throw std::bad_alloc();
}
~Buffer() {
delete [] array;
}
std::size_t size() const { return bound; }
unsigned char* data() { return array; }
private:
Buffer(const Buffer& b);
Buffer& operator=(const Buffer& b);
unsigned char* array;
std::size_t bound;
};

struct freebuffer : std::unary_function<void,Buffer*> {
void operator()(Buffer* b) {
delete b;
}
};

struct findbuffer : std::unary_function<bool,Buffer*> {
findbuffer(unsigned char* tofind) : val(tofind) { }
bool operator()(Buffer* b) {
return (b->data() == val) ? true : false;
}
private:
unsigned char* val;
findbuffer();
};

struct capacitycounter : std::unary_function<void,Buffer*> {
capacitycounter(std::size_t* p) : val(p) { *val = 0; }
void operator()(Buffer* b) { *val += b->size(); }
private:
std::size_t* val;
};

class BufferFactory {
private:
BufferFactory(const BufferFactory& b);
BufferFactory& operator=(const BufferFactory& b);
std::deque<Buffer*> known;
public:
BufferFactory() {}
unsigned char* make(std::size_t cap) throw (std::bad_alloc) {
Buffer* b = new Buffer(cap);
known.push_front(b);
return b->data();
}
void free(unsigned char* p) {
std::deque<Buffer*>::iterator it =
std::find_if(known.begin(), known.end(), findbuffer(p));
if (it != known.end()) {
Buffer* b = *it;
delete b;
known.erase(it);
}
return;
}
std::size_t size() const {
std::size_t s;
std::for_each(known.begin(), known.end(), capacitycounter(&s));
return s;
}
~BufferFactory() {
std::for_each(known.begin(), known.end(), freebuffer());
}
};

}//detail

#if !defined (TESTING)
template <int N>
#endif
class CubixFactory
{
public:
#if defined (TESTING)
static const int N = 4;
#endif
typedef float** Cubix[N];
typedef std::size_t Plane[N];

private:

CubixFactory(const CubixFactory& c);
CubixFactory& operator=(const CubixFactory& c);

detail::BufferFactory bfact;

public:

CubixFactory() { }

Cubix* make(const Plane hplane, const Plane vplane) {

// do one honkin alloc
unsigned char* data;
std::size_t data_size = sizeof(float****) +
N * sizeof(float***);
for (int i=0; (i < N); i++)
data_size += hplane[i] * sizeof(float*) *
vplane[i] * sizeof(float);
try {
data = bfact.make(data_size);
} catch (...) {
#if defined (OUTPUTTEST)
std::cerr << data_size << " failed alloc" << std::endl;
#endif
throw;
}

// layer view onto data
Cubix* vals;
int offset = 0;
vals = (Cubix*)data;
offset += 1 * sizeof(Cubix*);

// overlay concept - since no cast to array
typedef float*** cons;
cons* cube = (cons*)data;
*cube = (cons)(data + offset); // use cons, no cast to Cubix
offset += sizeof(cons) * N;
// end of overlay concept
#if defined (OUTPUTTEST)
static float test_cnt = 0;
#endif
for (int h=0; (h < N); h++) {
(*vals)[h] = (float**)(data + offset);
offset += hplane[h] * sizeof(float*);
for (int i=0; (i < hplane[h]); i++) {
(*vals)[h][i] = (float*)(data + offset);
offset += vplane[h] * sizeof(float);
#if defined (OUTPUTTEST)
for (int j=0; (j < vplane[h]); j++) {
(*vals)[h][i][j] = test_cnt++;
}
#endif
}
}
return vals;
}

void dump(Cubix* vals) {
unsigned char* data = (unsigned char*)vals;
bfact.free(data);
}

std::size_t allocated() const { return bfact.size(); }

~CubixFactory() { }
};

#if defined(OUTPUTTEST) || defined (CAPACITYTEST)
const int Bound = 4;
#if defined (TESTING)
typedef CubixFactory Factory;
#else
typedef CubixFactory<Bound> Factory;
#endif
typedef Factory::Plane Plane;
typedef Factory::Cubix Cubix;

void output(const Plane hplane, const Plane vplane,
Cubix* c, const char* s)
{
#if defined (OUTPUTTEST)
std::cout << '\n' << s << '\n';
for (int h=0; (h < Bound); h++) {
for (int i=0; (i < hplane[h]); i++) {
for (int j=0; (j < vplane[h]); j++) {
std::cout << (*c)[h][i][j] << '\t';
}
std::cout << '\n';
}
}
std::cout << '\n';
#endif
}

int main() {
#if defined (CAPACITYTEST)
Plane h = { 1024, 16, 16, 16 };
Plane v = { 768, 16, 16, 16 };
Plane hh = { 10240, 160, 160, 160 };
Plane vv = { 7680, 160, 160, 160 };
try {
Factory f;
Cubix* xbuffer = f.make(hh, vv);
} catch (std::bad_alloc& e) {
std::cerr << "\npassed bad alloc test\n" << std::endl;
}
#else
Plane h = { 2, 3, 8, 4 };
Plane v = { 6, 2, 3, 2 };
#endif
try {
Factory f;
Cubix* xbuffer = f.make(h, v);
Cubix* ybuffer = f.make(h, v);
output(h, v, ybuffer, "ybuffer");
Cubix* zbuffer = f.make(h, v);
std::cout << "factory memory use: " << f.allocated() <<
std::endl;
f.dump(ybuffer);
std::cout << "factory memory use after dump ybuffer: " <<
f.allocated() << std::endl;
output(h, v, zbuffer, "zbuffer");
f.dump(zbuffer);
std::cout << "factory memory use after dump zbuffer: " <<
f.allocated() << std::endl;
output(h, v, xbuffer, "xbuffer");
f.dump(xbuffer);
std::cout << "factory memory use after dump xbuffer: " <<
f.allocated() << std::endl;
xbuffer = f.make(h, v);
ybuffer = f.make(h, v);
zbuffer = f.make(h, v);
std::cout << "factory memory use after realloc: " << f.allocated() <<
std::endl;
output(h, v, xbuffer, "xbuffer");
output(h, v, ybuffer, "ybuffer");
output(h, v, zbuffer, "zbuffer");
} catch (...) {
std::cerr << "in main and got unexpected exception" << std::endl;
throw;
}
// destruction of factory object deletes all "made" objects
std::cout << "\npassed tests" << std::endl;
}
#endif


1 2
Next ›   Last »