Showing posts with label High performance. Show all posts
Showing posts with label High performance. Show all posts

Saturday, 13 July 2024

What is it with the AMD Adrenaline Software?

Very quick one, I've taken delivery of a new Graphics Card... (oooooo ahhhhh).

And it's a seed change for me as this is my first ever AMD graphics card, so this is of course going in my own main PC, which itself is my first ever AMD CPU powered machine I am therefore all Team Red for the first time ever... EVER!
I have been so excellently impressed with the performance of the Ryzen Zen 2 chip at the heart of my machine and my old EVGA 1080 GTX Superclocked was showing its age.  It was therefore time.

Unfortunately I made a huge mistake... No, it wasn't the model, no it wasn't the price, no it wasn't even paying to import it (because it was cheaper by a margin to have the card fly all the way to me through customs from California than actually buy it here in the UK - Thanks Brexit! - Not).

Anyway, it arrived and I plugged it in, and my monitor didn't come to life; I then found the signal was going to my massive 4K TV (on the HDMI) not my monitor (on the display port - go figure).

That sorted I then needed drivers, so I went to the AMD site and looked and found what it said was the best package to install on Windows 10 64bit for this card....

I don't know ANYTHING about the AMD software, and oh boy is that a mistake.

I installed it and was immediately REALLY REALLY IMPRESSED with it!  Yep, it's beautiful (even if it is backed by Qt and I hate Qt) and smooth and does wonderful things.

Unfortunately, and this is key, it was taking a lot of CPU whilst doing this work... So I closed it... and it STILL took a bunch of CPU, nearly 10%!

Just idle at the desktop, 10% CPU.

I was properly baffled by this, it must be doing something, so I went through all the settings and disabled everything I could see, everything turned off, clean reboot, and it was still taking 10% but now was peaking to 14% on odd occasions just idle!

What the heck, a bunch of goodling and I can find a bunch of folks complaining about exactly this, and one guy properly threatening to boycott their brand unless they explain how to just install the drivers without this software suite.  There was no answer to these please, and they were old posts, like there's been an apparent hard reset of the search results for this kind of question.

I spent a bunch of time trying to fathom this issue to no avail, so I like my forebears in the search results set about trying to find JUST a driver package.  I could not find one,

I therefore just decided to pull the card and possibly return it.  And so uninstalled the AMD Adrenaline Software, it took its time... And really grated on me as it spent about two minutes showing me the text "We value your feedback"... without ever giving me a link or contact in order to tell them anything... and this is during an uninstall process; surely someone when they added this eye stabbing annoying message thought "Oh we need to have them able to give me feedback!" ... Nope, seems not.

Now completely uninstalled and the package opens a website... This website... which I link only for you to see... as it's an advert... for a version of the very card I am uninstalling the software for.... Yes, AMD that's pretty tone deaf, also... WITHOUT YOUR DRIVERS INSTALLED YOU CAN NOT VIEW THAT SITE, so double double own goal there .... Less Advanced Micro Devices and Anyone Might Despair.


Here I am then, flabbergasted, back to a tiny resolution, opening chrome and trying to find just a raw driver package and I can't find one.  My machine has now cooled and I hear the CPU pump has ceased whirring away, as it was constantly with the 10% load on it!

I sat looking for ages when I first installed the card, really ages, we're taking an hour before I went with this Adrenaline stuff.

When suddenly Windows itself kicks into life and installs the Microsoft supplied WHQL driver, and guess what?  Yes, it's the same base driver, and it works absolutely brilliantly... and crucially my machine is not taking any CPU when idle, it's gone quite quen idle, I'm sat now typing this with a YouTube video playing, about 6 chrome tabs open and a copy of Visual Studio Code open too and it is silent, the machine is silent, just as I built it to be (unless under load).

Looking about I see AMD are recruiting software engineers, I have no idea what for, but if they see these pages - I'd suggest a bunch of refactoring is due over there folks.

Thursday, 27 December 2018

C++ High Performance - Mistaken Statements

I am a huge fan of using the language to communicate my intent, especially when it comes to function parameters, I've talked about this before in terms of simple typing (by utilising "using" statements - to give meaning to simple/trivial types) and const correctness.


But being Christmas, I've had a C++ gift or two, and one of them is C++ High Performance by Victor Sehr and Bjorn Andrist, I've only spent a few minutes looking through this book, but one comment did jump out at me as odd... Not overtly wrong, just odd to me, maybe a different way to look at things...


No, I'm not talking about their constant calling back to compare with Java (rolls eyes) I'm talking about the two stanza's at the bottom:

"C++ Arguments passed as references indicates that null values are not allowed"

No, no that's not the point of references, the point is that you do not allocate memory for and copy the values from the passed resource into a local value for use within the function which will have a scope life-time of the function and therefore be de-allocated at the end of the function.  A reference, to me, has always primarily been a method of communicating copy semantics, we're referencing the remote value, if the parameter is not constant it maybe modified, thus:

#include <iostream>
#include <string>

int g_value(42);

void Change(int& p_Value)
{
p_Value += 1;
}

int main()
{
std::cout << "Before: " << g_value << "\r\n";
Change(g_value);

std::cout << "After: " << g_value << std::endl;
}

Or not modified, thus:

#include <iostream>
#include <string>

int g_value(42);

void Change(int& p_Value)
{
p_Value += 1;
}

void Print(const std::string& p_Pre, const int& p_Value)
{
std::cout << p_Pre << ": " << p_Value << "\r\n";
}

int main()
{
Print("Before", g_value);
Change(g_value);

Print("After", g_value);
}

If we were to allocate a value as a pointer we could send the reference to these same functions and they would be unaware of subtle problems (without modern runtime checks):

#include <iostream>
#include <string>

int g_value(42);

int *g_PointedToMemory(new int{ 100 });

void Change(int& p_Value)
{
p_Value += 1;
}

void Print(const std::string& p_Pre, const int& p_Value)
{
std::cout << p_Pre << ": " << p_Value << "\r\n";
}

int main()
{
Print("Before", g_value);
Change(g_value);
Print("After", g_value);


std::cout << "--------------\r\n";

Print("Pointed To Before", *g_PointedToMemory);
Change(*g_PointedToMemory);
Print("Pointed To After", *g_PointedToMemory);
}

With modern runtime checks this code would still compile, you are not "defending" from null pointers by using the reference syntax, you're simply stating not to take a separate copy of the thing being passed in.  However, if you dereferenced a null pointer (nullptr) int* as the parameter being passed, the code would still compile, but you would receive a runtime access violation, as you're trying to write to nullptr.

#include <iostream>
#include <string>

int g_value(42);

int *g_PointedToMemory(new int{ 100 });

int *g_Unallocated(nullptr);

void Change(int& p_Value)
{
p_Value += 1;
}

void Print(const std::string& p_Pre, const int& p_Value)
{
std::cout << p_Pre << ": " << p_Value << "\r\n";
}

int main()
{
Print("Before", g_value);
Change(g_value);
Print("After", g_value);

std::cout << "--------------\r\n";

Print("Pointed To Before", *g_PointedToMemory);
Change(*g_PointedToMemory);
Print("Pointed To After", *g_PointedToMemory);

std::cout << "--------------\r\n";

Print("Unallocated Before", *g_Unallocated);
Change(*g_PointedToMemory);
Print("Unallocated After", *g_Unallocated);

}

This code is clearly dereferencing an unallocated piece of memory, it builds no problem... This is where my mind skews on the comment in this text, it's a throw away line, but so miss leading to my eyes.


But this code will not run:


This is where I totally take issue with the statement in the text.

Getting this kind of runtime error, because we've followed the advice of this text, we may move onto the next line of the advice:

"C++ arguments passed as pointers indicates that null values are being handled"... EREEEEERGGGGH.  No it does not, lets look at that, lets follow Alice down this rabbit hole with a new function, to take our unallocated integer pointer and try to dereference and print it... The text tells us "null" are being handled, we'll be fine, let us update our code:

#include <iostream>
#include <string>

int g_value(42);

int *g_PointedToMemory(new int{ 100 });

int *g_Unallocated(nullptr);

void Change(int& p_Value)
{
p_Value += 1;
}

void Print(const std::string& p_Pre, const int& p_Value)
{
std::cout << p_Pre << ": " << p_Value << "\r\n";
}

void PrintPtr(const std::string& p_Pre, const int* p_Value)
{
std::cout << p_Pre << ": " << *p_Value << "\r\n";
}

int main()
{
Print("Before", g_value);
Change(g_value);
Print("After", g_value);

std::cout << "--------------\r\n";

Print("Pointed To Before", *g_PointedToMemory);
Change(*g_PointedToMemory);
Print("Pointed To After", *g_PointedToMemory);

std::cout << "--------------\r\n";

// The alternative Print
PrintPtr("Unallocated Before as Pointer", g_Unallocated);

std::cout << "--------------\r\n";

Print("Unallocated Before", *g_Unallocated);
Change(*g_PointedToMemory);
Print("Unallocated After", *g_Unallocated);

}

And now lets run the program again...

Yes, it explodes, with the exact same runtime error... yet the text said "null values are being handled".  And it is just totally untrue, the truth is that pointers like this simply mean you can pass something which points to the memory you want to use (passing a pointer is like passing a small number of bytes - depending on your architecture - rather than passing a reference to the memory a pointer maybe anywhere in the addressable memory space, and it does not have to necessarily be a pointer from "new" or "make_shared" (etc) it can be any memory...

So, we could make this PrintPtr function print our allocated "g_value" from the earlier pieces of code, by making the call with a dereferencing:

I am going to plug on with this book, I hope to find another hour tomorrow to start going through their advice for speeding up modern C++.  Unfortunately, right now, I am surprise and somewhat dismayed with this miss-leading stance, and I have three other pages folded down to follow up on this exact theme, the text taking you slightly off of course or making statements which are not correct C++ nor correct thinking.