Sign in to follow this  
mychii

Optimization issue when using operator=

Recommended Posts

Hi guys,

 

I am still getting into C++ and messing around with comparing a simple hand-written Vec2 with glm's vec2, and I kinda found a quite funny result.

 

Code first:

#include <iostream>
#include <string>
#include <chrono>

#include <glm/vec2.hpp>

class Vec2
{
public:
	float a;
	float b;

	Vec2()
	{

	}

	Vec2(float a, float b) : a(a), b(b)
	{
		
	}

	~Vec2()
	{

	}

	void operator=(Vec2 const& v)
	{
		// it doesn't even do anything yet.
	}

	Vec2& operator*(Vec2 const& v)
	{
		this->a *= v.a;
		this->b *= v.b;

		return *this;
	}
};

int main()
{
	auto t_start = std::chrono::high_resolution_clock::now();

	Vec2 v{ 2.0f, 2.0f };
	Vec2 vv{ 2.0f, 2.0f };
	Vec2 vr;

	for (int i = 0; i < 10000000; ++i)
	{
		vr = vv;
	}

	auto t_end = std::chrono::high_resolution_clock::now();

	std::cout << std::fixed << std::chrono::duration<double, std::milli>(t_end - t_start).count() << std::endl;

	t_start = std::chrono::high_resolution_clock::now();

	glm::vec2 v2{ 2.0f, 2.0f };
	glm::vec2 v22{ 2.0f, 2.0f };
	glm::vec2 vres;

	for (int i = 0; i < 10000000; ++i)
	{
		vres = v22;
	}

	t_end = std::chrono::high_resolution_clock::now();

	std::cout << std::fixed << std::chrono::duration<double, std::milli>(t_end - t_start).count() << std::endl;

	return 0;
}

I make a simple assignment using my Vec2 operator= for 10m iterations. It takes roughly around 390ms compare to glm's vec2 that is 28ms on my machine. I even removed the code inside it, it is still like that. This is completely the opposite when I'm doing a multiplication (operator*), which is ~410ms vs ~668ms.

 

So assume there's something wrong or missing when I'm doing operator=, but I really don't know what it is.

I've tried to get as close as glm's code I saw in type_vec2.inl.

 

Cheers~

Edited by Alectora

Share this post


Link to post
Share on other sites
A good compiler should optimize away your entire test. Therefore, it is dangerous to make assumptions based on what you have here.

EDIT:
Redacted-- Frob is right, I forgot which board I was posting in.
Also, upon a second look, I realized that operator* is probably a typo of operator*=

My post is useless. Edited by fastcall22

Share this post


Link to post
Share on other sites

@Juliean

Ah, silly me, I forgot the release mode.  :P

I was trying to make a simple code without templates and all to see if it makes a difference. But you've explained it nicely to make me realize this doesn't do a thing.

 

On top of that, your vector operators aren’t well formed.

 

Can you tell me what the "well-formed" should be? is it cause I didn't return anything on that assignment? It's the reason why I post it in Beginner section.

Edited by Alectora

Share this post


Link to post
Share on other sites

@frob

Oh my, okay, that's very deep. I didn't know it could go that far down to assembly. :blink:

 

About the templates, this is what I always do in JavaScript cause this does matter on that level as everything happened during runtime, including generic codes.

So whenever I see any generalization and stuff, I have this habit to check its performance and see if the simplification of the code would make a difference.

 

My main case was I only need float-based vectors. By that, my mind says why would I need a generic version of it and then tries to check if it does make a difference by runtime performance.

I will re-read C++ template again.  :rolleyes:

 

Thanks for the time, guys!

Edited by Alectora

Share this post


Link to post
Share on other sites

Optimizing compilers do an awful lot.

 

As you mentioned getting a start in JavaScript, you probably understand how different JavaScript systems generate different results.  Running the same JavaScript code in different browsers can give radically different performance even though the JavaScript is identical. 

 

The same is true in C++ and other languages.  Different compilers and different compiler settings can result in big differences in how the code actually executes.  

 

The only way to make a truly fair comparison is to consider how the code actually executes all the way through in a non-trivial example. It needs to do actual work, then you can look and see how the system actually runs in a real-world environment. 

Share this post


Link to post
Share on other sites

@frob

True, Sir! Learned myself a new homework for that now. This is excitingly new to me.  :rolleyes:

 

@SeanMiddleditch

Thanks for telling me how things are going on. Didn't realize it's not that simple. :wacko:

 

The assignment was supposed to have simple assignment code which is this->a = v.a and this->b = v.b. When I put those, it "gave" me a slow result, so I was assuming that removing these code to empty may increase the speed, which apparently not. Therefore I posted the empty one. But as everyone has explained, it's completely not the point.

 

Also, upon a second look, I realized that operator* is probably a typo of operator*=

Thanks for the clarification fastcall22. I just copied the glm code (just without template) and use that operator instead of the '*='  one for a (fail) comparison.  :)

Edited by Alectora

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