Reputation: 7015
I was recently surprised to note that compiling with /GS
(Enable buffer security check) in MSVC++ 2010 seems to have a non-negligible effect on run-time performance in some cases. Has anyone else had this experience??
For a large scientific-style application (a mesh generation library) it seems that compiling with /GS-
can lead to almost 10% improvements in run-time for several of the large benchmarks in my test suite ("large" being >= 1 second worth of run-time). /GS
is on by default at all levels of optimisation in MSVC++ 2010.
I must admit that I'd never paid too much attention to this option before, and I'm wanting a bit of clarification as to what it actually does. The online documentation seems to talk extensively about string buffers, but since I don't use string
or char[]
buffers anywhere I must be missing something.
This paragraph (from the online doc) seems to indicate that the performance degradation I'm seeing is a bit unusual:
A performance tradeoff for using security checks in an application must be made. The Visual C++ compiler team focused on making the performance degradation small. In most cases, the performance should not degrade more than 2 percent. In fact, experience has shown that most applications, including high-performance server applications, have not noticed any performance impact.
Of course I can just turn it off, and get faster code, but I want to understand the implications before I do that.
Upvotes: 14
Views: 13292
Reputation: 29
TrendMicro will flag your application as suspicious for compiling with /GS- for performance.
TrendMicro-HouseCall Suspicious_GEN.F47V0828.
It seems they also ignore all requests to re-evaluate as false positive.
Upvotes: 2
Reputation: 151
I've had the same experience as you: /GS- leading to ~10% improvements in runtime. I've shared some benchmarks on my blog: The Cost of Buffer Security Checks in Visual C++
When /GS is enabled (which is the default for the VC++ Release configuration), it seems anytime you create a C-style array as a local variable, the compiler will insert a few extra instructions to ensure the 4 bytes following the array on the stack have not been modified. As you've noticed, it doesn't seem to matter if it's a char array, or an array of another type. I guess the idea behind this compiler option is that any stack buffer overflow could be exploited by hackers, regardless of type.
But if you’re developing a Visual C++ application which is not a network service, and you’re striving for maximum performance, such as in a game, editor, or benchmarking tool — and it’s unlikely to be targeted by hackers — then I'd suggest to go ahead and disable this option.
Upvotes: 15
Reputation: 2276
/GS adds code that tries to detect if a write overrun or similar stack attack has happend during a function, and to stop execution after a write overrun. The patterns that it aims to find are ones that have been seen in real-world attacks. There are a bunch of real world security bulletins that would not have happened if today's /GS had been in use at the time.
In this case a write overrun can happen on structures, arrays and various other entities. Changes and improvements to /GS are made in each version of VS. More /GS protection generally has cost, although in some cases newer VS may have learnt how to do the same protection cheaper.
I'd recommend leaving /GS on unless your code doesn't ship to others - generally the protection is worth the cost; at most you might choose to disable it for specific functions where there is no risk and high impact - just as you might hand-optimise the most critical parts of your program in other ways.
Martyn
Upvotes: 14