Skip to main content
gamedev.net
🔒 Locked

State Hash

Started by Jman2 Oct 22, 2019 at 8:21 AM 2 replies 1.9k views
Original Post
Jman2
Jman2

Hello,

Im currently hashing states like the code sample below, is there a more elegant way of doing this? or should i just cache the hash in the struct and default 0 as being "null" and hope i dont get a collision where one eventrually resolves to 0.


struct RASTERIZER_DESC
{
	FILL_MODE         m_FillMode              = FILL_SOLID;
	CULL_MODE         m_CullMode              = CULL_BACK;
	VERTEX_WIND_ORDER m_VertexWind            = WIND_FRONT_CLOCKWISE;
	int               m_DepthBias             = 0;
	float             m_DepthBiasClamp        = 0.0f;
	float             m_SlopeScaledDepthBias  = 0.0f;
	bool              m_DepthClipEnable       = true;
	bool              m_MultisampleEnable     = false;
	bool              m_AntialiasedLineEnable = false;

	Uint32 GetHash()const
	{
		Uint32 hash = 23;

		hash = hash * 31 + (Uint32)m_FillMode;
		hash = hash * 31 + (Uint32)m_CullMode;
		hash = hash * 31 + (Uint32)m_VertexWind;
		hash = hash * 31 + (Uint32)m_DepthBias;
		hash = hash * 31 + (Uint32)m_DepthBiasClamp;
		hash = hash * 31 + (Uint32)m_SlopeScaledDepthBias;
		hash = hash * 31 + (Uint32)m_DepthClipEnable;
		hash = hash * 31 + (Uint32)m_MultisampleEnable;
		hash = hash * 31 + (Uint32)m_AntialiasedLineEnable;

		return hash;
	}
};


a light breeze
a light breeze

Three tips:

  1. Don't write your own hashing function. I use boost::hash, but you may find another that suits you better.
  2. Don't cast your floating point values to Uint32. This will drop all fractional values, i.e. 0.5 and 0.0 will hash to the same value, and it will overflow for large values. I think what you meant was reinterpret_cast(&m_DepthBias). Or better: std::hash()(m_DepthBias).
  3. Caching the hash value makes sense for big data structures. I would say that your RASTERIZER_DESC is on the border - small enough to fit into a single cache line, but big enough that the calculation itself could be a performance problem if you need to do it a million times per frame..


Jman2
Jman2
1 hour ago, a light breeze said:

Three tips:

  1. Don't write your own hashing function. I use boost::hash, but you may find another that suits you better.
  2. Don't cast your floating point values to Uint32. This will drop all fractional values, i.e. 0.5 and 0.0 will hash to the same value, and it will overflow for large values. I think what you meant was reinterpret_cast(&m_DepthBias). Or better: std::hash()(m_DepthBias).
  3. Caching the hash value makes sense for big data structures. I would say that your RASTERIZER_DESC is on the border - small enough to fit into a single cache line, but big enough that the calculation itself could be a performance problem if you need to do it a million times per frame..


  1. True.
  2. Yeah didnt notice that, kind of bulk wrote the hashes for all the structs's, swapping them out to std::hash.
  3. I think, i will go with a cache hash and treat 0 as null, the chance of cycling around and landing on 0 is unlikly.

Thanks for the tips!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.