Access Violation in nvopengl.dll

  • Follow


Hi all,

I'm receiving an access violation error when calling glDrawElements as
follows:

glDrawElements (GL_TRIANGLES, iTris*3, GL_UNSIGNED_SHORT,
&pGeometrySet->Faces()[0]);

The function Faces() returns a pointer to an array of unsigned shorts,
so it returns a pointer to a pointer.

The error is being reported as occuring in NVOGLNT! 69785962(), the
debugger halts on the following bit of assembly:

69785962   mov         ebp,dword ptr [eax]

Any ideas would be most appreciated.

Thanks v.much in advance,
Ben.
0
Reply brm 7/23/2003 3:39:23 PM

Ben wrote:
> 
> Any ideas would be most appreciated.
> 

I think you haver a bug in your program somewhere.
Either a pointer is wrong, or a size is wrong, or...


-- 
<\___/>          For email, remove my socks.
/ O O \
\_____/  FTB.    Why isn't there mouse-flavored cat food?



0
Reply fungus 7/23/2003 4:01:20 PM


Hi Ben,

Which graphics driver are you using? Is it NVIDIA's or an OEM's update
for NVIDIAs? I ran into a similar problem with an Asus driver for a
GeForce-series card. Their drivers had some debug code in them, but
since you don't have source code, the error message goes to the
machine code for the OpenGL driver. In the release-mode drivers, this
would go to the last line in your source before the problem

If you don't need any special features from your OEM graphics card,
I'd suggest installing NVIDIA's own drivers. They are typically more
stable and faster. That fixed my problem.

Rob Targosz
robtargosz@hotmail.com

On 23 Jul 2003 08:39:23 -0700, brm@morrisb.fsnet.co.uk (Ben) wrote:

>Hi all,
>
>I'm receiving an access violation error when calling glDrawElements as
>follows:
>
>glDrawElements (GL_TRIANGLES, iTris*3, GL_UNSIGNED_SHORT,
>&pGeometrySet->Faces()[0]);
>
>The function Faces() returns a pointer to an array of unsigned shorts,
>so it returns a pointer to a pointer.
>
>The error is being reported as occuring in NVOGLNT! 69785962(), the
>debugger halts on the following bit of assembly:
>
>69785962   mov         ebp,dword ptr [eax]
>
>Any ideas would be most appreciated.
>
>Thanks v.much in advance,
>Ben.

0
Reply Rob 7/24/2003 2:22:20 AM

This has happened to me a few times before as well, but it always turns 
out that one of my calls to gl...Pointer is supplying a wrong pointer!
In other words, make sure all your pointers are pointing to the right 
place, and that you haven't (by mistake) enabled more arrays than you think.

Anders

Ben wrote:
> Hi all,
> 
> I'm receiving an access violation error when calling glDrawElements as
> follows:
> 
> glDrawElements (GL_TRIANGLES, iTris*3, GL_UNSIGNED_SHORT,
> &pGeometrySet->Faces()[0]);
> 
> The function Faces() returns a pointer to an array of unsigned shorts,
> so it returns a pointer to a pointer.
> 
> The error is being reported as occuring in NVOGLNT! 69785962(), the
> debugger halts on the following bit of assembly:
> 
> 69785962   mov         ebp,dword ptr [eax]
> 
> Any ideas would be most appreciated.
> 
> Thanks v.much in advance,
> Ben.

0
Reply Anders 7/24/2003 7:51:12 AM

You are pointing to non allocated memory :

Vertex Array : [X0,Y0,Z0], [X1, Y1, Z1], ..., [Xn, Yn, Zn]
Your face pointer [0, 4, 7, 2, n+1, 2, ... ]
The (n+1) is asking for some vertex that does not exist.

Multiple reasons for this :
- It could be that you forgot to disable some client states, as
instance if your model has no vertex color, and you enabled this
client array, then it will fail.
- Your array pointers point to non allocated memory, or you didn't
specify any pointer.
- Or maybe all your arrays are not of the same size, the vertex array
is size n, the normal array is size n-4, and you pass index n-2, that
works well for verticies, but not for normals.


SeskaPeel.


brm@morrisb.fsnet.co.uk (Ben) wrote in message news:<cf0e12df.0307230739.7a2d124e@posting.google.com>...
> Hi all,
> 
> I'm receiving an access violation error when calling glDrawElements as
> follows:
> 
> glDrawElements (GL_TRIANGLES, iTris*3, GL_UNSIGNED_SHORT,
> &pGeometrySet->Faces()[0]);
> 
> The function Faces() returns a pointer to an array of unsigned shorts,
> so it returns a pointer to a pointer.
> 
> The error is being reported as occuring in NVOGLNT! 69785962(), the
> debugger halts on the following bit of assembly:
> 
> 69785962   mov         ebp,dword ptr [eax]
> 
> Any ideas would be most appreciated.
> 
> Thanks v.much in advance,
> Ben.
0
Reply seskapeel 7/24/2003 8:58:12 AM

Cheers Anders. It was glColorPointer. I have graduated from vertex
colors to using materials and failed to switch of the enabling of the
color pointer as my face's color is now the diffuse component of a
material.

A quick question, am I right in thinking that you EITHER use vertex
colors to color faces OR materials but NOT BOTH?

Cheers,
Ben.

Anders Brodersen <rip@daimi.au.dk> wrote in message news:<bfo33q$r5t$1@news.net.uni-c.dk>...
> This has happened to me a few times before as well, but it always turns 
> out that one of my calls to gl...Pointer is supplying a wrong pointer!
> In other words, make sure all your pointers are pointing to the right 
> place, and that you haven't (by mistake) enabled more arrays than you think.
> 
> Anders
> 
> Ben wrote:
> > Hi all,
> > 
> > I'm receiving an access violation error when calling glDrawElements as
> > follows:
> > 
> > glDrawElements (GL_TRIANGLES, iTris*3, GL_UNSIGNED_SHORT,
> > &pGeometrySet->Faces()[0]);
> > 
> > The function Faces() returns a pointer to an array of unsigned shorts,
> > so it returns a pointer to a pointer.
> > 
> > The error is being reported as occuring in NVOGLNT! 69785962(), the
> > debugger halts on the following bit of assembly:
> > 
> > 69785962   mov         ebp,dword ptr [eax]
> > 
> > Any ideas would be most appreciated.
> > 
> > Thanks v.much in advance,
> > Ben.
0
Reply brm 7/24/2003 11:16:58 PM

Hi Rob,

Thanks for the reply mate it turned out to be me enabling vertex
colors but not passing them to the pipeline as I've recently started
using materials to color faces instead.

As it turns out i installed a better driver as a result of your mail
so thatnks for the advice.

Cheers,
Ben.

Rob Targosz <robtargosz@hotmail.com> wrote in message news:<ieguhv0jade9j5tsb7lup47ejjcrb67hvk@4ax.com>...
> Hi Ben,
> 
> Which graphics driver are you using? Is it NVIDIA's or an OEM's update
> for NVIDIAs? I ran into a similar problem with an Asus driver for a
> GeForce-series card. Their drivers had some debug code in them, but
> since you don't have source code, the error message goes to the
> machine code for the OpenGL driver. In the release-mode drivers, this
> would go to the last line in your source before the problem
> 
> If you don't need any special features from your OEM graphics card,
> I'd suggest installing NVIDIA's own drivers. They are typically more
> stable and faster. That fixed my problem.
> 
> Rob Targosz
> robtargosz@hotmail.com
> 
> On 23 Jul 2003 08:39:23 -0700, brm@morrisb.fsnet.co.uk (Ben) wrote:
> 
> >Hi all,
> >
> >I'm receiving an access violation error when calling glDrawElements as
> >follows:
> >
> >glDrawElements (GL_TRIANGLES, iTris*3, GL_UNSIGNED_SHORT,
> >&pGeometrySet->Faces()[0]);
> >
> >The function Faces() returns a pointer to an array of unsigned shorts,
> >so it returns a pointer to a pointer.
> >
> >The error is being reported as occuring in NVOGLNT! 69785962(), the
> >debugger halts on the following bit of assembly:
> >
> >69785962   mov         ebp,dword ptr [eax]
> >
> >Any ideas would be most appreciated.
> >
> >Thanks v.much in advance,
> >Ben.
0
Reply brm 7/24/2003 11:28:42 PM

SeskaPeel wrote:
>
> If I was the software engineer, I would not use new[], I'd rather use
> std::vector. 

Good advice.

If you're using new[] or malloc in a C++ program then
you're probably doing something wrong.


-- 
<\___/>          For email, remove my socks.
/ O O \
\_____/  FTB.    Why isn't there mouse-flavored cat food?



0
Reply fungus 7/24/2003 11:56:04 PM

> A quick question, am I right in thinking that you EITHER use vertex
> colors to color faces OR materials but NOT BOTH?

No. You can use both, but rendering may become tricky if you wish to
use both diffuse material and vertex color, for diffuse painting.
Toggling GL_COLOR_MATERIAL will only affect diffuse and ambient
parameters of your material. It means that for each vertex, the
material is used to paint your mesh.
You can still use specular and self illum material properties.

SeskaPeel.
0
Reply seskapeel 7/25/2003 8:30:14 AM

On 24 Jul 2003 16:16:58 -0700, brm@morrisb.fsnet.co.uk (Ben) wrote:

>Cheers Anders. It was glColorPointer. I have graduated from vertex
>colors to using materials and failed to switch of the enabling of the
>color pointer as my face's color is now the diffuse component of a
>material.

One check I added into my gfx engine yesterday was to check that with
objects you want to render, I check every index to see if it is within
range.
These OpenGL memory bugs can otherwise be hard to trace!

Mostly though when you crash inside your driver, it's a bad feeding of
some data. That means arrays most always.


Ruud van Gaal
Free car sim: http://www.racer.nl/
Pencil art  : http://www.marketgraph.nl/gallery/
0
Reply KILLSPAMruud 7/25/2003 11:16:22 AM

On 25 Jul 2003 01:30:14 -0700, seskapeel@hotmail.com (SeskaPeel)
wrote:

>> A quick question, am I right in thinking that you EITHER use vertex
>> colors to color faces OR materials but NOT BOTH?
>
>No. You can use both, but rendering may become tricky if you wish to
>use both diffuse material and vertex color, for diffuse painting.
>Toggling GL_COLOR_MATERIAL will only affect diffuse and ambient
>parameters of your material. It means that for each vertex, the
>material is used to paint your mesh.
>You can still use specular and self illum material properties.

What was that 'trick' again, where you could use vertex coloring but
STILL add lighting effects per vertex? (as the vertex color is the
same entity as where the lighting is stored, right?)


Ruud van Gaal
Free car sim: http://www.racer.nl/
Pencil art  : http://www.marketgraph.nl/gallery/
0
Reply KILLSPAMruud 7/25/2003 11:17:46 AM

Hello, fungus!
You wrote  on Thu, 24 Jul 2003 23:56:04 GMT:

 >> If I was the software engineer, I would not use new[], I'd rather use
 >> std::vector.

 f> Good advice.

 f> If you're using new[] or malloc in a C++ program then you're probably
 f> doing something wrong.

the good point in C++ is that low-level C-style code and high-level class
code can be easily mixed in it. pure high-level C++ for _everything_ can
both significanly degrade performance(up to many times) and increase
complexity(decreasing readablitity), so you can have potentially more bugs
with less speed. compilation speed of template-rich code can be 10 times and
more slower than simple code, with big enough projects this can lead to
slowing down development.
i use OOP only for big enough objects which are not created/accessed/deleted
very frequently, so there will be no performance penaulties of using them.

With best regards, Alex Mizrahi aka killer_storm.


0
Reply Alex 7/25/2003 2:15:39 PM

Cheers Seska - I'll take another glance at the red book. Have a good weekend.

Ben.

seskapeel@hotmail.com (SeskaPeel) wrote in message news:<8b17baaa.0307250030.71665cca@posting.google.com>...
> > A quick question, am I right in thinking that you EITHER use vertex
> > colors to color faces OR materials but NOT BOTH?
> 
> No. You can use both, but rendering may become tricky if you wish to
> use both diffuse material and vertex color, for diffuse painting.
> Toggling GL_COLOR_MATERIAL will only affect diffuse and ambient
> parameters of your material. It means that for each vertex, the
> material is used to paint your mesh.
> You can still use specular and self illum material properties.
> 
> SeskaPeel.
0
Reply brm 7/25/2003 2:52:27 PM

Cheers for the reply wolfgang - I've attached a snippet of code that
demo's the kind of thing I'm doing with regards to alloc/dealloc of
memory. If you see any probs with this I'd be grateful if you could
let me know - PS Have a good weekend ;-)

The code...

By the way m_pVertices is a float[], m_pFaces is an unsigned short[]
etc...

	GeometrySet::GeometrySet(){
		m_pVertices		= 0;
		m_iNoOfVertices	= 0;

		m_pNormals			= 0;
		m_iNoOfNormals	= 0;

		m_pColors			= 0;
		m_iNoOfColors		= 0;

		m_pFaces			= 0;
		m_iNoOfFaces		= 0;

		m_iMaterialID		= 0;
	}

	GeometrySet::~GeometrySet(){
		if(m_pVertices != 0){delete[] m_pVertices;}
		if(m_pNormals != 0){delete[] m_pNormals;}
		if(m_pFaces != 0){delete[] m_pFaces;}
		if(m_pColors != 0){delete[] m_pColors;}
	}

	void GeometrySet::SetVertexCount(MAGE_INT iVertexCount){			
		
		if(iVertexCount <= 0){
			if(!m_pVertices == 0){
				delete[] m_pVertices;
				m_pVertices		= 0;
				m_iNoOfVertices	= 0;
			}
		}
		else{
			if(m_pVertices == 0){
				m_pVertices = new MAGE_FLOAT[iVertexCount*3];
			}else{
				if(iVertexCount != m_iNoOfVertices){
					delete[] m_pVertices;
					m_pVertices = new MAGE_FLOAT[iVertexCount*3];
				}
			}
			m_iNoOfVertices = iVertexCount;
		}			
	}

Wolfgang Draxinger <wdraxinger@darkstargames.de> wrote in message news:<bfp7vo$18o$1@svr8.m-online.net>...
> Ben wrote:
> > Hi all,
> > 
> > I'm receiving an access violation error when calling glDrawElements as
> > follows:
> > 
> > glDrawElements (GL_TRIANGLES, iTris*3, GL_UNSIGNED_SHORT,
> > &pGeometrySet->Faces()[0]);
>  
> > 69785962   mov         ebp,dword ptr [eax]
> That not so important. This line says just, that some content of memory 
> is to be copied from address stored in eax into ebp.
> The access violation means, that the memory at this position is 
> protected, and thus not valid.
> 
> BTW:
> This line
> &pGeometrySet->Faces()[0]
> is equivalent to
> pGeometrySet->Faces()
> 
> I don't know your code so I can just guess:
> First guess, that you wrote something like this in
> <something>::Faces()
> {
> ...
> GLuint *faces=new GLuint[nfaces];
> ...
> return faces;
> }
> 
> This complete valid code. But then, where do you free the memory you 
> aquired. You called the function within the parameter list of 
> glDrawElements. So you've no change to delete this memory.
> 
> Second guess:
> <something>::Faces()
> {
> GLuint faces[<some_number>];
> ...
> return faces;
> }
> Now you've the problem, that faces is on the stack and thus destroyed, 
> when the function Faces() returns.
> 
> Third guess:
> You class just has a member value faces and Faces() returns this one.
> Then you must look at the point where you aquired memory.
> Oftenly it happens, that you aquire to less memory, but as long you only 
> use the data within you program all works well. But as soon you use the 
> code in some external context, e.g. OpenGL you run into memory protection.
> This is, because new memory is always allocated within so called 
> "pages", that have a certain block size. When changing into kernel 
> context the memory boundaries are locked for security reasons. Then an 
> access beyond the buffer boundaries will cause an access violation.
> 
> So just make sure, that you aquired enough memory. This error is so 
> common when using Vertex Arrays, that it is the first I'm looking for in 
> this context.
> 
> Hope this helps.
> 
> Wolfgang
> --
0
Reply brm 7/25/2003 2:59:47 PM

Alex Mizrahi wrote:

>  f> If you're using new[] or malloc in a C++ program then you're probably
>  f> doing something wrong.
> 
> the good point in C++ is that low-level C-style code and high-level class
> code can be easily mixed in it. pure high-level C++ for _everything_ can
> both significanly degrade performance(up to many times)

Disagree. With the exception of virtual functions, C++
code will be exactly the same as C code.

Virtual functions are have an extra pointer fetch
but on a modern CPU the decoder is looking ahead and
will pre-fetch it for you so there's no penalty unless
it hasn't been called for a while and causes a cache
miss. I doubt you can measure the difference between
virtual/non virtual functions with a modern CPU/compiler.


> and increase complexity(decreasing 
> readablitity), so you can have potentially more bugs
> with less speed.

Totally disagree. std::vector will significantly *reduce*
bugs compared to new[] and malloc precisely because the
code is a lot cleaner (eg. You don't have to worry about
who deletes the memory, you don't have to keep track of
sizes and pass them around all over the place as parameters)
I was suspicious when I first got a C++ compiler so I spent
an afternoon looking at the compiler output. I found that
std::vector mostly produces *identical* code to the C
version. Compiler writers are clever people and you can
bet what you like that they'll take great pains to make
sure that operator[] is as efficient as c arrays. Similarly
for iterators, they produce identical code to for() loops
which use a pointer.

As for strings... I'd like to see a piece of complex string
manipulation code where std::string is messier than C strings.
malloc and new[] can easily become a nightmare to use for
things like parsing complex files and checking for errors.
Making sure you don't leak memory when you abort something
in C can easily double the size of your code and you'll
never be sure you got it right. In C++ you can throw an
exception and stack unwinding will make sure that all
memory is freed for you. No worries.

Then there's buffer overflows and stuff. C++ objects grow
as needed so they pretty much eliin mate this problem. You
can do it in C using realloc() but why bother? Your code
will be worse and you're rewriting the same old code again
so you might be putting new bugs in.

> compilation speed of template-rich code can be 10 times and
> more slower than simple code, with big enough projects this
 > can lead to slowing down development.

If your compiler is ten times slower then you need a new
compiler instead of throwing away a very valuable programming
technique.

Sure, templates can be misused....(in fact they usually are IMHO,
I don't think I have more than half a dozen in my entire program)
but using C arrays instead of std::vector is madness.


If you only ever use one C++ feature then use std::vector, you
won't ever regret it. I promise.


> i use OOP only for big enough objects which are not created/accessed/deleted
> very frequently, so there will be no performance penaulties of using them.
> 

I don't know what these "performance penalties" are, but OOP
is a design process, not a coding process. It doesn't make
your programs either slower or faster in my experience.



-- 
<\___/>          For email, remove my socks.
/ O O \
\_____/  FTB.    Why isn't there mouse-flavored cat food?



0
Reply fungus 7/25/2003 5:57:52 PM

Hello, fungus!
You wrote  on Fri, 25 Jul 2003 17:57:52 GMT:

 f>>> If you're using new[] or malloc in a C++ program then you're
 f>>> probably doing something wrong.

 >> the good point in C++ is that low-level C-style code and high-level
 >> class code can be easily mixed in it. pure high-level C++ for
 >> _everything_ can both significanly degrade performance(up to many
 >> times)

 f> Disagree. With the exception of virtual functions, C++
 f> code will be exactly the same as C code.

 f> Virtual functions are have an extra pointer fetch but on a modern CPU
 f> the decoder is looking ahead and will pre-fetch it for you so there's
 f> no penalty unless it hasn't been called for a while and causes a
 f> cache miss. I doubt you can measure the difference between
 f> virtual/non virtual functions with a modern CPU/compiler.

non-virtual functions can be inline. inlining can greatly improve speed, up
to many times.
modern C++ is not just about some classes with virtual functions, it
typically deals with templates. templates greatly depend on inlining(so
debug version can be slow as hell), and they somewhat obscure optimizations.
previous versions of compilers - msvc6 and ioc5 - as i remember did not
fully optimize math code for vector class with operators(wich were all
inline), so it was significantly slower than C-like code.  i didn't tried
newer compilers - msvc.NET and ioc6, but most likely this will again be
slower than C-like code.

 f> I was suspicious when I first got a C++ compiler so I spent an
 f> afternoon looking at the compiler output. I found that std::vector
 f> mostly produces *identical* code to the C version. Compiler writers
 f> are clever people and you can bet what you like that they'll take
 f> great pains to make sure that operator[] is as efficient as c arrays.
 f> Similarly for iterators, they produce identical code to for() loops
 f> which use a pointer.

i've tested vector<float> code compared to float[].. in msvc.NET there
really was almost no difference, but intel optimizing c++ compiler 6 decided
to vectorize only plain old float[] code.
so results are such:

plain old float[]:
ioc6 - 0.01187
msvc.net - 0.02906
delphi7 - 0.056

vector<float>:
msvc.net - 0.031
ioc6 - 0.067

as you see, vector<float> cannot(at least on compilers i have, i dont have
ioc7) fully use power of Intel Pentium4, that leads to 3 times performance
decrease.
with plain old data i can have more control - for example, align data on
good address, so it can be more easily vectorized.

 f> Then there's buffer overflows and stuff. C++ objects grow as needed
 f> so they pretty much eliin mate this problem. You can do it in C using
 f> realloc() but why bother? Your code will be worse and you're
 f> rewriting the same old code again so you might be putting new bugs
 f> in.

i have my own template for dynamic arrays that uses realloc() instead of
copying to new location(as std::vector does).
but i use it's data as plain old C array.

 >> compilation speed of template-rich code can be 10 times and more
 >> slower than simple code, with big enough projects this
 >> can lead to slowing down development.

 f> If your compiler is ten times slower then you need a new compiler
 f> instead of throwing away a very valuable programming technique.

i have msvc6, msvc.NET and ioc6. all slower. you have better compilers?

With best regards, Alex Mizrahi aka killer_storm.


0
Reply Alex 7/26/2003 12:07:27 PM

Ben wrote:

>>A quick question, am I right in thinking that you EITHER use vertex
>>colors to color faces OR materials but NOT BOTH?
>>    
>>
SeskaPeel replied

>No. You can use both, but rendering may become tricky if you wish to
>use both diffuse material and vertex color, for diffuse painting.
>Toggling GL_COLOR_MATERIAL will only affect diffuse and ambient
>parameters of your material. It means that for each vertex, the
>material is used to paint your mesh.
>You can still use specular and self illum material properties.
>
>SeskaPeel.
>  
>
I'm sorry, but I don't think you can use "vertex color" and "material 
properties" at the same time.
Lighting is either off (vertex color) or on (material properties).

Now, with lighting on, you have 4 material properties for front faces 
and 4 for back faces:

Emissive
Ambient
Diffuse
Specular

Emissive material properties are simply added to the colors from 
lighting calculations,
so yes, you can mix lighted colors with non-lighted ("self illum") 
colors -- perhaps that
is what  you mean?

If you enable GL_COLOR_MATERIAL, you can "connect" glColor to glMaterial, so
that calls to glColor (and color vertex arrays) are equivalent to 
glMaterial calls, with
an argument of GL_EMISSIVE, GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR and
the special GL_AMBIENT_AND_DIFFUSE which copies the color to two
material properties.

And yes, you can call glMaterial per vertex multiple times, so you can 
specify all
the material properties for a vertex.

-- Andy V, the OpenGL pedant


0
Reply Andy 7/26/2003 1:23:36 PM

Alex Mizrahi wrote:

> non-virtual functions can be inline. inlining can greatly 
 > improve speed, up to many times.

Yes of course... but real world code isn't very likely to
call virtual operator[] in a tight loop. Real life virtual
functions will typically be used in a way where the advantages
from a programming point of view will far outweigh any possible
speed penalty. If not, you need to tske a good look at your
design.

 > modern C++ is not just about some classes with virtual
 > functions, it typically deals with templates.

I think templates are massively overused. There was an
example here a couple of weeka ago where people were
using templates to write an OpenGL camera class so you
coulc have "float" cameras and "double" cameras. This
is madness to me. If you're doing that then you haven't
analysed the problem properly. Also, by filling your code
with "Camera<float>" you're actually naking it less flexible
when a simple typedef in the header file would suffice.


> i've tested vector<float> code compared to float[].. in msvc.NET there
> really was almost no difference, but intel optimizing c++ compiler 6 decided
> to vectorize only plain old float[] code.
> so results are such:
> 

What "benchmark" is this? I bet a few simple tweaks
would probably fix it.

Still, "write first, profile later" should apply to all
code. By assuming that std::vector will be slower you're
probably making your life much more complicated than
necessary.

> i have my own template for dynamic arrays that uses realloc() instead of
> copying to new location(as std::vector does).
> but i use it's data as plain old C array.
> 

realloc() doesn't need to copy data to a new location?
That's news to me...



-- 
<\___/>          For email, remove my socks.
/ O O \
\_____/  FTB.    Why isn't there mouse-flavored cat food?



0
Reply fungus 7/26/2003 2:34:30 PM

Hello, fungus!
You wrote  on Sat, 26 Jul 2003 14:34:30 GMT:

 >> modern C++ is not just about some classes with virtual functions, it
 >> typically deals with templates.

 f> I think templates are massively overused. There was an example here a
 f> couple of weeka ago where people were using templates to write an
 f> OpenGL camera class so you coulc have "float" cameras and "double"
 f> cameras. This is madness to me. If you're doing that then you haven't
 f> analysed the problem properly.

oh, this is not worst thing done with templates - it's what they are
designed for(but i dont see any need of templates here too).  stl sometimes
exploits
templates much more, in places which - i believe - can be handled by
compiler easily, w/o huge constuctions. "boost" library exploits templates
more than stl. and i've heard about even more perversions with them.. one
guy as i remember tried to do compile-time sort with them, but somewhat
failed with recursive templates.

 f> Also, by filling your code with "Camera<float>" you're actually naking
 f> it less flexible when a simple typedef in the header file would suffice.

it can be done such that float will be default and Camera<> will be used, or
making class that will be template specialization. but it will have sence
only if somebody uses both float and double cameras in one projects.

 >> i've tested vector<float> code compared to float[].. in msvc.NET
 >> there really was almost no difference, but intel optimizing c++
 >> compiler 6 decided to vectorize only plain old float[] code.
 >> so results are such:


 f> What "benchmark" is this? I bet a few simple tweaks would probably
 f> fix it.

no, it's simpliest piece of code and nothing can be tweaked to force ioc to
vectorize it, i think.

 f> Still, "write first, profile later" should apply to all code.

i need to do some benchmarking first to define most efficient instruments
first. if wrong way will be chosen, it can cost very much of time and
efforts.

 f> By assuming that std::vector will be slower you're probably making your
 f> life much more complicated than necessary.

well, maybe..

 >> i have my own template for dynamic arrays that uses realloc() instead
 >> of copying to new location(as std::vector does).
 >> but i use it's data as plain old C array.

 f> realloc() doesn't need to copy data to a new location?
 f> That's news to me...

realloc does not copy data to new location if there is enogh space after
existing block. i've looked through crt implementation, looks like they
really implemented this properly.

With best regards, Alex Mizrahi aka killer_storm.



0
Reply Alex 7/26/2003 7:41:51 PM

Alex Mizrahi wrote:

> 
> oh, this is not worst thing done with templates - it's what they are
> designed for(but i dont see any need of templates here too).  stl sometimes
> exploits
> templates much more, in places which - i believe - can be handled by
> compiler easily, w/o huge constuctions. "boost" library exploits templates
> more than stl.

I'm not too keen on the "boost" library myself.

> and i've heard about even more perversions with them.. one
> guy as i remember tried to do compile-time sort with them, but somewhat
> failed with recursive templates.
>

Yes, there's always somebody....

Many entries in the obfusticated C contest do things
like thar - using the preprocessor to do the computation,
etc.

> it can be done such that float will be default and Camera<> will be used, or
> making class that will be template specialization. but it will have sence
> only if somebody uses both float and double cameras in one projects.
> 

Which is exactly ny point I think. There is no reason to ever
use a "float" camera.


Other classes are less clear. eg having both float and double
matrix classes might be reasonable.

>  f> Still, "write first, profile later" should apply to all code.
> 
> i need to do some benchmarking first to define most efficient instruments
> first. if wrong way will be chosen, it can cost very much of time and
> efforts.
> 

The whole point of OO programming is to define the interfaces.

After that you're free to fiddle with the implementation as
much as you want to. The profiler will tell you where the
problems are and you can tweak those classes.


>  f> By assuming that std::vector will be slower you're probably making your
>  f> life much more complicated than necessary.
> 
> well, maybe..
> 

Read the FAQ:

>  f> realloc() doesn't need to copy data to a new location?
>  f> That's news to me...
> 
> realloc does not copy data to new location if there is enogh space after
> existing block. 
> 

That's quite a big "if".

Whatever, you're free to replace the std::vector class if
you want to. Write the code first using STL, profile, *then*
decide what it is that makes it slow.

eg. I wrote a replacement for std::string which has a 64 byte
buffer for small strings so no extra memory allocation is
performed unless the string is bigger than 64 bytes. In a
program which creates a lot of small, temporary strings this
is a *big* speedup.

Note however that I wrote the program first using STL, profiled,
*then* found out where the bottleneck was (in the memory allocations). 
So long as my replacement string class has the same interface as
std::string then it will all compile and work, except it was three
or four times faster.



-- 
<\___/>          For email, remove my socks.
/ O O \
\_____/  FTB.    Why isn't there mouse-flavored cat food?



0
Reply fungus 7/27/2003 5:50:27 AM

>  f> realloc() doesn't need to copy data to a new location?
>  f> That's news to me...
> 
> realloc does not copy data to new location if there is enogh space after
> existing block. i've looked through crt implementation, looks like they
> really implemented this properly.

This is exactly the same for std::vector.
What's more, if you use std::deque, it can even add data in front of
the array. There are additional problems with std::deque, but it's a
good point of view to get that stl is here to help, and is designed
specifically for this.

I won't be argueing about this again, and again, and again ... C is
good for small apps, C++ is the evidence for larger apps. With my
humble experience, a 3D engine is a big app, I'll go for C++
everywhere, so that anyone in the team can easily debug, maintain,
evolve, any piece of code of any person ...

Before being a 3D programmer, be a software engineer,
SeskaPeel.
0
Reply seskapeel 7/29/2003 9:03:36 AM

Hello, SeskaPeel!
You wrote  on 29 Jul 2003 02:03:36 -0700:

 f>>> realloc() doesn't need to copy data to a new location?
 f>>> That's news to me...

 >> realloc does not copy data to new location if there is enogh space
 >> after existing block. i've looked through crt implementation, looks
 >> like they really implemented this properly.

 S> This is exactly the same for std::vector.

maybe you'll take a look at <vector> first? it can only grow w/o new
allocation when data fits in Capacity, it's not able just grab next memory
block if it's free.
and because of C++ it cannot simply copy memory blocks as realloc can do -
it tries to call copy constructor for each element. so, if you have
vector<char> and want to simply copy data it will do a lot of checks and
copy byte by byte instead of simple "rep movsd"! and if i have not a trivial
char constructor(for example I want to throw exception if value it more that
100), it will do a call for each element, i think, only because there may be
some rare(maybe not even existing in real life) cases when it's needed.
so std::vector is not the same..

 S> What's more, if you use std::deque, it can even add data in front of
 S> the array.

if it reserved space for it..
std::allocator gives only two methods - allocate and deallocate, and smart
stl types can work only with such allocators, they cannot work with memory
manager directly. so, there always will be some overhead - because of memory
reservation or because of frequent reallocation.

 S> There are additional problems with std::deque, but it's a good point of
 S> view to get that stl is here to help, and is designed specifically for
 S> this.

 S> I won't be argueing about this again, and again, and again ... C is
 S> good for small apps,

have you tried languages other than C/C++? Perl, PHP, Java, VB, Object
Pascal(Delphi)? there are a lot of situations when they are better than
C/C++..

 S> C++ is the evidence for larger apps. With my humble experience, a 3D
 S> engine is a big app, I'll go for C++ everywhere, so that anyone in the
 S> team can easily debug, maintain, evolve, any piece of code of any person
 S> ...

there are a lot of coding styles that C++ supports. you can do old C way
looking procedure-based program, but build on smart stl types - map, pair,
vector - and it will be C++ program w/o defining own classes except stl
template specializations. or you can define C++ classes for large enough
blocks and design interfaces for them, but use old C style for what's in
implemenation.. MFC and ATL are both written on C++, but they look
completely different. C++ programming does not mean using stl templates
everywhere. there are some cases when they are really very good - for
example, map class, algorithms like sort, lower_bound - but inserting them
everywhere can impact compilation and execution speed, make code less
readable..

With best regards, Alex Mizrahi aka killer_storm.


0
Reply Alex 7/29/2003 1:50:04 PM

Alex Mizrahi wrote:
> 
> and because of C++ it cannot simply copy memory blocks as realloc can do -
> it tries to call copy constructor for each element. so, if you have
> vector<char> and want to simply copy data it will do a lot of checks and
> copy byte by byte instead of simple "rep movsd"!

You don't know that. For a simple class which only contains
primitives (nothing with copy contructors) the compiler
can (and usually will) generate "movsd".

> so std::vector is not the same..
> 

For simple things like arrays of vertices, the
difference is not enough to worry about.

Careful use of reserve() will minimize data copying.

>  S> What's more, if you use std::deque, it can even add data in front of
>  S> the array.
> 
> if it reserved space for it..

No, deque works with blocks of memory, the data in
it isn't continuous in memory like std::vector.
A deque can add another block to the front of an
array, no problem.

A deque doesn't move around memory as it grows,
when a deque is full it allocates another block
of memory and adds it to the end, none of the
data in the deque will be copied/moved. It can
be a *lot* more efficient than a std::vector in
the right circumstances. The penalty is that
operator[] is a bit more complex.

> have you tried languages other than C/C++? Perl, PHP, Java, VB, Object
> Pascal(Delphi)? there are a lot of situations when they are better than
> C/C++..

Of course...but this is an OpenGL forum and I think that
C++ is usually the best tool for writing 3D graphics
programs as it supports both object oriented *and* low
level programming in the same language.


> there are a lot of coding styles that C++ supports. you can do old C way
> looking procedure-based program, but build on smart stl types - map, pair,
> vector - and it will be C++ program w/o defining own classes except stl
> template specializations. or you can define C++ classes for large enough
> blocks and design interfaces for them, but use old C style for what's in
> implemenation.. MFC and ATL are both written on C++, but they look
> completely different. C++ programming does not mean using stl templates
> everywhere. there are some cases when they are really very good - for
> example, map class, algorithms like sort, lower_bound - but inserting them
> everywhere can impact compilation and execution speed, make code less
> readable..
> 

C++ is a language, not a methodology, it doesn't
force you to write in any particular way.

You can say "this program is written using C++", but
you can never say "this is a C++ program".


-- 
<\___/>          For email, remove my socks.
/ O O \
\_____/  FTB.    Why isn't there mouse-flavored cat food?



0
Reply fungus 7/29/2003 5:04:18 PM

> oh, this is not worst thing done with templates - it's what they are
> designed for(but i dont see any need of templates here too).  stl
sometimes
> exploits
> templates much more, in places which - i believe - can be handled by
> compiler easily, w/o huge constuctions. "boost" library exploits templates
> more than stl. and i've heard about even more perversions with them.. one
> guy as i remember tried to do compile-time sort with them, but somewhat
> failed with recursive templates.
Well, it's not really a problem to make compile-time sort for smth (maybe
for typelist to ensure that subclasses follow superclasses or smth like it,
Andrei Alexandrescu actually did it in Loki, so there's really not much of a
problem :)), just define the criteria and build recursive template.
Compile-time algorithms are often useful when dealing with generic things,
like Functors or Multimethods, generalized patterns etc..
BTW template-based metaprogramming looks somewhat like functional
programming (languages like Clean or Haskell), but a bit more frightening
:).
Generally it's somewhat like strategical code generation, concentrating not
"how", but "what" is needed, what strategies are used to achieve the result.
So, like those functional languages, generic metaprogrammings often leads to
slower, even many times slower, and ineficcient code.


0
Reply Vladimir 8/3/2003 8:57:46 AM

Hello, fungus!
You wrote  on Tue, 29 Jul 2003 17:04:18 GMT:

 >> and because of C++ it cannot simply copy memory blocks as realloc can
 >> do -
 >> it tries to call copy constructor for each element. so, if you have
 >> vector<char> and want to simply copy data it will do a lot of checks
 >> and copy byte by byte instead of simple "rep movsd"!

 f> You don't know that. For a simple class which only contains
 f> primitives (nothing with copy contructors) the compiler can (and
 f> usually will) generate "movsd".

maybe you'll show me some examples?  i'm telling so because i've looked in
disassembly.

for simpliest copy:
vector<char> hellou1(4096);
vector<char> hellou2(4096);
hellou2 = hellou1;

both MSVC.NET 2002 and Intel C++6 generate code(for = operator, "Release"
version with all default settings - optimize for speed) with dozens of
checks and copying loop looking like:

mov cl,byte ptr [edx]
inc edx
mov byte ptr [eax],cl
inc eax
cmp edx,ebx
jne 00401AC6

when it's done like
char * hellou1 = (char*) malloc(4096);
char* hellou2 = (char*) malloc(4096);
memcpy(hellou2, hellou1, 4096);

memcpy is 3 asm instruction, loop is "rep movsd".
feel the difference?

With best regards, Alex Mizrahi aka killer_storm.



0
Reply Alex 8/14/2003 12:38:29 PM

Alex Mizrahi wrote:
> Hello, fungus!
> > vector<char> hellou1(4096);
> vector<char> hellou2(4096);
> hellou2 = hellou1;
> 
> both MSVC.NET 2002 and Intel C++6 generate code(for = operator, "Release"
> version with all default settings - optimize for speed) with dozens of
> checks and copying loop looking like:
> 
> mov cl,byte ptr [edx]
> inc edx
> mov byte ptr [eax],cl
> inc eax
> cmp edx,ebx
> jne 00401AC6
> 

That�s not quite what I meant....

Try this:

class foo {
  int a,b,c,d,e,f,g,h;
};

std::vector<foo>a(128), b(128);
a = b;


VC++ 6.0 does the copy with:

rep movs dword ptr [edi],dword ptr [esi]


For a vector copy, C++ has to call operator= for each
element in the vector. It can't string them together
into one big copy (well, in theory it could but it
doesn't seem to) but it will copy each individual
element with movs.

eg.

class foo {
  int a,b,c,d,e,f,g,h;
};

std::vector<foo>a(128), b(128);
a = b;

With VC++ 6.0 I get this code:

004011C1   mov         edi,dword ptr [ebp+8]
004011C4   add         dword ptr [ebp+8],20h
004011C8   mov         esi,edx
004011CA   push        8
004011CC   add         edx,20h
004011CF   cmp         edx,eax
004011D1   pop         ecx
004011D2   rep movs    dword ptr [edi],dword ptr [esi]
004011D4   jne         004011C1


Whatever, the advice stands. Write first using the best
coding practices, *then* if it's not fast enough, profile
it and find where the problems are.

Outside of this sort of argument, in a real life program,
I bet you don't actually do a lot of vector assignments
in your inner loops, right? I bet that most vector copying
happens via push_back, and careful use of reserve() will
avoid this.

If this is so then you're worrying over nothing. Why lose
the safety and power of std::vector just because they don't
copy well in little theoretical programs?



-- 
<\___/>          For email, remove my socks.
/ O O \
\_____/  FTB.    Why isn't there mouse-flavored cat food?



0
Reply fungus 8/14/2003 1:18:21 PM

25 Replies
117 Views

(page loaded in 0.237 seconds)

Similiar Articles:


















7/15/2012 6:12:39 PM


Reply: