Advertisement

State Hash

Started by October 22, 2019 08:21 AM
2 comments, last by Jman2 5 years, 3 months ago

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;
	}
};

 

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<UInt32 *>(&m_DepthBias).  Or better: std::hash<float>()(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..

 

Advertisement
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<UInt32 *>(&m_DepthBias).  Or better: std::hash<float>()(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!

This topic is closed to new replies.

Advertisement