Sign in to follow this  
V-man

qwerty

Recommended Posts

int array[100]; memset(array, 1, sizeof(sint)*100); instead of filling up array with 1, it fills up with 0x01010101 Is that normal and what would be a better function to use? edit : sorry about the title. I guess I forgot to change it. [Edited by - V-man on July 7, 2007 8:48:53 PM]

Share this post


Link to post
Share on other sites
That's how it works. It filled the array with the character sized variable 1 (0x0F or 00001111b).

The reason 0 works to fill it with all 0s is because it is made of all 0x itself (0x00 or 00000000b).

If you want to fill it up with all 1s, then use the number made of all 1s (11111111b = 0xFF = 255)

memset(array,255,sizeof(int)*100);

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
int array[100];
memset(array, 1, sizeof(sint)*100);

instead of filling up array with 1, it fills up with 0x01010101
Is that normal and what would be a better function to use?


Yes, this is normal -- memset only deals with the concept of bytes.

If this is C++, you should prefer it's standard library options when available over the legacy inherited from C (which memset is a part of). In this case, C++ has std::fill available:

int array[100];
std::fill( array, array+100, 1 );


std::fill is a template (and thus C++ only) function, which allows it to detect that array is a bunch of ints, and fill on a per-int basis instead of a per-byte basis. Note that you don't even need sizeof() anymore. It will also work with iterators if you're not using a raw array like you are in this example.

Share this post


Link to post
Share on other sites
About std:fill, thanks, I didn't know about it until now.
I prefer to use "raw arrays" instead of std classes. It is a question of personal taste and memory alignment, although I use C++.
I was wondering if there is a good old fashion alternative.

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
About std:fill, thanks, I didn't know about it until now.
I prefer to use "raw arrays" instead of std classes. It is a question of personal taste, although I use C++.


So in other words you don't use C++.

Do you have some reason for this decision?

Share this post


Link to post
Share on other sites
int array[100];
memset(array, 1, sizeof(sint)*100);

0x01010101 0x01010101 0x01010101 ...


--------------------------------

int array[100];
memset(array, 1, sizeof(int)*100);

0x00000001 0x00000001 0x00000001


-me

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
Memory alignment I guess is the technical reason.


Meaning what?

Are you trying to ensure the memory allocated is contiguous? Because std::vector does that automatically.

If you're trying to ensure that your memory is 4 8 or 16 byte aligned for some reason you can probably do that too though I'll defer to the more expert members of the forum for the best way's to do so.

Share this post


Link to post
Share on other sites
"If you're trying to ensure that your memory is 4 8 or 16 byte aligned for some reason you can probably do that too though I'll defer to the more expert members of the forum for the best way's to do so."

yes

Also, it's difficult to watch during debugging. I used VC++6 and now .NET 2003
If I use the std::vector class and if I were to put my variable in the watch window like this

mything[0]

it gives an error message :
error : object "mything" doesn't have an indexer

I've never figure this out. Anyone know what's the matter with MS-VC?

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
Memory alignment I guess is the technical reason.

Using the default allocator, C++ containers will give you the same alignment guarantees as C-style arrays.

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
I've never figure this out. Anyone know what's the matter with MS-VC?


Lots of things were wrong with 6.0. For starters, it was released pre-standard and thus does not support a lot of features of the C++ language. 2003 is much better, but still had sub-par standard library debugging, IMO. 2005 is much better at that sort of thing, and the express edition is free (and highly recommended).

Share this post


Link to post
Share on other sites
1) For the love of all that is holy, put some thought into your thread title.

2)
Quote:
Original post by erissian
That's how it works. It filled the array with the character sized variable 1 (0x0F or 00001111b).

The reason 0 works to fill it with all 0s is because it is made of all 0x itself (0x00 or 00000000b).

If you want to fill it up with all 1s, then use the number made of all 1s (11111111b = 0xFF = 255)

memset(array,255,sizeof(int)*100);


I (and others) assume he wants to fill the array with ints of value 1, rather than with all set bits.

3)
Quote:
Original post by Palidine
int array[100];
memset(array, 1, sizeof(sint)*100);

0x01010101 0x01010101 0x01010101 ...


--------------------------------

int array[100];
memset(array, 1, sizeof(int)*100);

0x00000001 0x00000001 0x00000001


Not the problem this time, but you should match these things up in general.

Although there is really no reason to use memset() in C++.

4)
Quote:
Original post by V-man
About std:fill, thanks, I didn't know about it until now.
I prefer to use "raw arrays" instead of std classes. It is a question of personal taste and memory alignment, although I use C++.
I was wondering if there is a good old fashion alternative.


a) std::fill *isn't* a class; it's a function. You are still using a "raw array" here; it's just a matter of how you specify how you're filling it.
b) The "std classes" are part of the standard library of the C++ language. Writing C++ code without them is like writing C code without the stuff found in stdio.h, stdlib.h etc. And there is a *lot* of stuff in there that you probably don't even realize (because many compilers let you get away with omitting those #includes even when they shouldn't, relying on "builtins" instead). If you're insistent on writing C code, though, please don't pretend you're writing C++.

5)
Quote:
Original post by V-man
Memory alignment I guess is the technical reason.


Like Sneftel said.

And yes, MSVC++ 6.0 is ancient. It boggles the mind how many people out there are still trying to make it work. Or for that matter, how many *new* beginning programmers are somehow ending up with it. I don't even know where or how you could find it any more.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Quote:
Original post by V-man
Memory alignment I guess is the technical reason.

Using the default allocator, C++ containers will give you the same alignment guarantees as C-style arrays.


It's not enough. I'm using some other function for 16 byte alignment.
_aligned_malloc and _aligned_free

Share this post


Link to post
Share on other sites
Quote:
Original post by Driv3MeFar
Quote:
Original post by V-man
I've never figure this out. Anyone know what's the matter with MS-VC?


Lots of things were wrong with 6.0. For starters, it was released pre-standard and thus does not support a lot of features of the C++ language. 2003 is much better, but still had sub-par standard library debugging, IMO. 2005 is much better at that sort of thing, and the express edition is free (and highly recommended).


But why does the same problem appear in VC++.NET 2003

I just tried with the latest VC++Express, it says
error : overloaded operator not found

I can only Watch the variable with
myarray._Myfirst[0]

Also, if anyone knows the C equivalent of memset for 32 bit writes, I would like to know. I ask because memset is efficient. It's better than writing a for loop.
int myarray[100];
for(i=0 i<mytotal; i++)
{
myarray[i]=myvalue;
}

[Edited by - V-man on July 10, 2007 10:42:58 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
It's not enough. I'm using some other function for 16 byte alignment.
_aligned_malloc and _aligned_free

Simple. Just declare your type as __declspec(align(16)) and C++ containers will do that for you.

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
Also, if anyone knows the C equivalent of memset for 32 bit writes, I would like to know. I ask because memset is efficient. It's better than writing a for loop.

Couldn't tell you offhand. On modern compilers, std::fill delegates to a tightly optimized routine written in assembler when you use it on things like integers. I guess C might have something like that, though it'd be compiler-dependent.

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
It's not enough. I'm using some other function for 16 byte alignment.
_aligned_malloc and _aligned_free


Then assuming you only want the array aligned to 16 byte boundaries you can use a custom allocator which allocated with _aligned_malloc and releases with _aligned_free or if you want the individual elements aligned then you can just declare the type with __declspec(align(16)) as Sneftel said.

Quote:
Couldn't tell you offhand. On modern compilers, std::fill delegates to a tightly optimized routine written in assembler when you use it on things like integers. I guess C might have something like that, though it'd be compiler-dependent.


To be more specific on VS05 std::fill will compile be equivalent to memset for all fundamental types and and types which satisfy __is_pod(type).

Share this post


Link to post
Share on other sites
From the looks of it, in .NET 2003 "xutility". it only uses memset for 8 bit types, else a standard for loop.

template<class _FwdIt,
class _Ty> inline
void fill(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
{ // copy _Val through [_First, _Last)
for (; _First != _Last; ++_First)
*_First = _Val;
}

inline void fill(char *_First, char *_Last, int _Val)
{ // copy char _Val through [_First, _Last)
::memset(_First, _Val, _Last - _First);
}

inline void fill(signed char *_First, signed char *_Last, int _Val)
{ // copy signed char _Val through [_First, _Last)
::memset(_First, _Val, _Last - _First);
}

inline void fill(unsigned char *_First, unsigned char *_Last, int _Val)
{ // copy unsigned char _Val through [_First, _Last)
::memset(_First, _Val, _Last - _First);
}


Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Simple. Just declare your type as __declspec(align(16)) and C++ containers will do that for you.

Until you try using the type with std::vector and the code blows up because the standard requires objects to be passed by value as arguments in some very fundamental function calls. Unfortunately there's no good work around for that (and keep the std::vector usage).

Share this post


Link to post
Share on other sites
You can't use memset() with non-POD types safely, so yes, it has to loop for those types it cannot specialize. memset() is typically an intrinsic (so it becomes the aforementioned assembly on release). This is at least true in VS2005, I'm pretty sure it was still the case in VS2003.

You can use custom allocators or compiler builtins (since _aligned_malloc is nonstandard anyway) to ensure your types are appropriately aligned the way you want. Boost might have some allocators prewritten, but they're not hard to build yourself. Of course you have to ensure your types size is appropriate as well, or you can't align it, period, in any contiguous container. Legally.

Are you sure this stuff is a bottleneck? Have you profiled it?

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
Quote:
Original post by Sneftel
Using the default allocator, C++ containers will give you the same alignment guarantees as C-style arrays.


It's not enough.


Please excuse me for not believing you. What are you trying to do that requires aligning things to 16-byte boundaries? People who need to do things that arcane are generally also people who can solve problems such as in the OP by themselves.

Share this post


Link to post
Share on other sites
Generally, to take advantage of SIMD instructions, your data must be properly aligned. IIRC, Altivec requires 16-byte alignment, I think SSE does as well. Very compute-intensive tasks like matrix multiplication, fixed-point/floating-point conversion, etc can be sped up by a factor of 4 (or more, with library's like SAL, which optimize for CPU cache configurations as well).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this