-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: temp allocation #757
Comments
And how would you expect the runtime to clear that memory without doing a GC? |
@Joe4evr |
@Joe4evr I think that's the easy part. If you know for sure that a group of objects can be safely freed at a specific point of time, you can use an arena to manage their memory. @ygc369 The general idea might sound enticing, but I have a hard time understanding how exactly would it work and how useful would it be in practice. For example, consider this code: Person[] GetAllPersonsByName(string name)
{
return this.persons.Where(p => p.Name == name).ToArray();
}
|
@svick |
In my opinion this belongs on the list of potential optimizations of the JIT, not of the language. C# has no concept of a free memory list. |
@HaloFour |
@ygc369 Why should it provide a syntax for it? |
@eyalsk |
@ygc369 How would this work? |
Specifically: what would the compiler actually do differently with this sort of code? |
I disagree. Such a thing, if it would exist, is an implementation detail of a CLR. As of now it doesn't exist in the CLR at all, let alone officially supported with public metadata in a manner that can be influenced by any of the CLR languages, let alone C#.
I'd suspect that the JIT would be more than capable of detecting when a local never escapes and could be safely collected upon exiting a method (blocks don't exist in IL and local slots are always scoped to the method). However, exactly what use is a variable that doesn't escape? What useful code could you possibly execute on |
@HaloFour |
Garbage collection handles that scenario just fine. If you're so obsessed about forcing the issue you can always set your references to |
@ygc369 If you can't mutate something and you can't get anything in and out of the block why do you need to allocate memory to begin with? can you name few of these algorithm? what's the problem with the following approach:
|
That sounds a lot like generational garbage collection: You have a small set of objects (Gen 0) and a subset of those objects that shouldn't be collected (roots). You walk references from the objects that shouldn't be collected to check which objects they reference (mark stage) and then deallocate the rest (sweep stage). Are you basically asking for explicitly delimited "gen -1"? |
Also, remember that in designing the CLR, the GC flow is intentionally left as an implementation detail. If you don't like that the GC is non-deterministic like that, then go to C/C++/any other unmanaged language where you can control literally every allocation and de-allocation yourself. But please just stop proposing all these silly micro-optimizations just because the GC doesn't behave in the way that you imagine it should. At the very least follow what you've been told time and again by now: Provide real-world performance data that shows beyond a shadow of a doubt that your proposed changes are worth the amount of time, effort, and money for Microsoft to change the existing system. |
@Joe4evr I take issue with your tone. It's not constructive. Please stop. Personally, I think the proposal is worth some thought. Just because the GC works in a certain way today doesn't preclude it from working different (better) in the future. I've had apps that have no choice but to call a function that allocates a block of memory and then throws it away a few instructions later, and this in a long-running tight loop. In this scenario the GC goes crazy with Gen 0 collections for millions of objects that logically have no reason to live so long. Explicitly setting them to null and forcing a collection just makes it worse. I've also heard is said, "if you need it faster, write it C/C++". This is great practical advise in the short term but my assumption is that these discussion about finding way to make .Net better. In which case such statements are not helpful. |
Again: what is the proposal here? What are you asking the C# compiler to actually do? |
You can usually accomplish this with pooled objects. That way you can have your temp values that you work with, but you don't churn the GC heavily as you can take those intermediate objects and put them in your pool instead of needing to have them be collected. |
GC proposals are probably not great to be here. This is the repo for the C# language. Details of the GC aren't really under our purview. |
In your example, i woudl advise changing that function that you are calling to behave differently. For example, instead of allocating data that then needs to be freed, it could be passed in the location to place or fill results. Then you could allocate once and it would not have to worry about that detail. If you can't change that function then it's highly unlikely that any proposal here would actually help with this. |
Ya. I'll get right on that...getting the .Net Framework and dozens of third party libraries to change their functions to behave differently. Ha! |
@ygc369 Note this issue was closed, I think, not because you idea has no merit but because it's not a language issue. Be sure to post you ideas to the coreclr for recommendations on better garbage collection. |
I don't understand what the proposal is. What do you think the .net framework could do differently here. Presumably if you wanted to use these constrained regions, you'd have to code in a very particular way (in order to participate properly with whatever restrictions it puts on your code). But... in the example given... you're calling out to 3rd party code. Code that expects to be run in a GC environment and would very likely not behave properly in such a new restrictive system. So again can someone please tell me what the request is, and how it would work, and how it would solve the problems laid out here?
Actually, this is definitely something you can do. Take a look at Stephen's post here https://blogs.msdn.microsoft.com/dotnet/2017/06/07/performance-improvements-in-net-core/ See how many performance improvements have been provided by the community. If you are having problems with .Net perf, then definitely put in the effort to address the issues. The PRs will get accepted, and it will be far more likely to happen, and far more likely to help than trying to get the language and runtime to change significantly here. -- Now, if you do want the language/runtime to change, it absolutely must be with a clearer description of what the proposal would be. I still can't tell what is being asked for here, so there's no way to make any forward progress on something like this. |
@SunnyWar |
@ygc369 @SunnyWar Could you provide information about your actual proposal? I"ve looked at the links to other proposals that you've made and they all seem to be lacking any sort of data or detail. To make a change or introduce a new .net memory model or programming model you absolutely must provide more information or else none of these issues are going to go anywhere. |
@CyrusNajmabadi |
@CyrusNajmabadi |
Can you explain your proposal more (and answer my question). What is the way that you would accomplish this? |
The JIT/CLR should ensure that. The rule is that non-temp objects can't reference any temp objects. Throw an exception when the rule is broken. |
Ok. let me try a different tactic. Imagine if i said "i want the runtime to do some sort of analysis and not allocate when it isn't necessary". Sure... that sounds great. But how does it do that? It's not enough to ask for these types of things, you have to actually explain how it would work. Be specific. What does the compiler and language do differently? How does the runtime actually implement this? How do we ensure that this doesn't break stuff. |
So you can't pass any of this data to anything else? For example, any method out there might end up taking any parameters and passing it to some referencing non-temp object. |
@CyrusNajmabadi
I can pass value type at least. |
These "temp" objects are just instances of normal reference types. Literally any method you could call, either instance or static, in literally any library anywhere, could take that reference and assign it somewhere. There's no way that the compiler nor the runtime can prevent another root from being established on these references and that would prevent the "temp" object from being collectable. |
I think this is related to dotnet/roslyn#161. It does actually propose to "destruct" objects once they're out of scope. and that in itself requires some kind of ownership as safety rules -- partly #421 though that doesn't propose to free memory once out of scope, just that we make sure that every object has a single owner to enforce immutability across aliases. |
@ygc369 Please take a look at these discussion on CoreCLR. https://github.com/dotnet/coreclr/issues/1784 |
If I understand the proposal you are making, you are essentially asking for a form of There are several proposals on the topic already of @CyrusNajmabadi could confirm, but I believe this is one of the issues where C# cannot do anything actionable until the CLR is modified to provide basic support for this functionality (e.g. more PRs like dotnet/coreclr#6653 need to be done). |
@tannergooding |
@ygc369 How would this work? How does your proposal make sure that it's safe to collect these objects? For example, if you wanted to "temp allocate" an object, then how would that work? First, how do you ensure that the constructor of the object doesn't leak 'this' to anything? Second, how do you ensure that any of the method you might pass this object to, or any of the methods you might call on this object, don't capture the object? Can you give an example of how this would work and how you could ensure it would be safe? |
For example, in your code, you have this:
What can you actually do with 's'? Any method call on 's' could cause it to escape. Can you provide an actual scenario where this would be useful and actually explain the proposal in more detail? So far i have not really seen any answers (sufficient or otherwise) for the questions i've asked you. |
@tannergooding I'm not suggesting anything. I'm only trying to get the jerks on this thread to open their minds a bit and consider the possibility of improving the status quo. That's why I pointed people at various proposals on the coreclr, so that they can familiarize themselves with other, similar, discussions. |
We'd need an actual proposal specifying how this would work. It would need to be clear about what changes to the language would be wanted, and how they would map to any underlying CLR functionality for the compiler implementation. I've now looked through each and every issue linked from this issue and i can't find anything actually concrete or actionable. It appears to be a lot of very high level request (like "we should support reference counting") without actually providing any sort of additional detail past that. These types of issues will not go anywhere in their current form. It would be akin to me saying "i want C# to be a cloud computing language" and then providing no detail on what that actually means or what it would actually entail to get there. @ygc369 If you are interested in this space (which certainly seems like the case given several messages from you asking if there has been any progress), then i would recommend supplying a little more information and design to help move things forward. Right now, opening an issue, and then hoping others will pick it up and figure it out isn't really going to be effective. |
@CyrusNajmabadi |
@CyrusNajmabadi |
Can you point to the java language feature that relates to escape analysis? |
I can only find Chinese documents about it. |
@CyrusNajmabadi's claim is that escape analysis is not a part of the Java language in that there is no syntax to opt-into using it or to influence it directly. It's an optional optimization feature of the runtime. |
@CyrusNajmabadi Wiki says this:
But really the only thing that baffles me here is why we need a new syntax for it? a new form of block that I still don't understand why the need to allocate memory if nothing gets in and out of it, maybe someone, smarter than me can explain it to me, do I miss anything? |
Value types can get out of it. static float GetInputSpeed()
{
int char_num=0;
Stopwatch sw = new Stopwatch();
sw.Start();
TempAllocationBlock
{
string s;
do {
s=Console.ReadLine(); //allocate temp strings
char_num += s.Length;
} while(s!="exit");
} //should free all temp strings here!
sw.Stop();
return ((float)char_num*1000*60)/(float)sw.ElapsedMilliseconds;
} |
Sorry, that's not how proposals work :) It doesn't suffice to just come, say you want something, and then say the onus is on us :) And, again, as mentioned by others, Java did this without the need for language changes. So why do we need language changes here?
Why does this require any language changes? The runtime already knows what is/isn't a value type. If it was doing escape analysis, surely it would only care about doing that for heap allocated instances. |
i don't understand how this works: TempAllocationBlock
{
string s;
do {
s=Console.ReadLine(); //allocate temp strings
char_num += s.Length;
} while(s!="exit");
} //should free all temp strings here! Are you saying that because we're in this TempAllocationBlock that any allocatoin in this block of execution will just get cleaned up once the block is exited? How do you ensure safety for that? What if Console.ReadLine does something internally like causing a segment to be allocated in some low level console stream that it's buffering from. Will that now get freed once you go out of this scope? |
@CyrusNajmabadi |
@ygc369 So if you knew about it days ago why didn't you post your conclusions about it back then? could have saved yourself and others some time. 😉 |
@eyalsk |
@ygc369 You don't get to decide when a discussion is over and closing an issue doesn't really mean it can't be discussed, otherwise, it was locking an issue and you don't get to do that, you didn't have to participate in the discussion but obviously, you chose to do so and that's good but I really find it strange that you knew about the issues @CyrusNajmabadi and other brought up and didn't bother to write about it but instead went on and closed the issue. It's like two people having a good conversation, one is trying to explain something, the other is trying to understand it, so the second person bringing up all sorts of questions and the moment the first person realizes he has no answers, he turns his back to the second person and yet the second person don't mind it and insists of getting answers so they continuing their conversation and throughout the discussion the first person realizes how wrong he is but instead of admitting it he says aye.... I knew that through the whole discussion but didn't bother to say anything about it this is why I turned my back on you. It just doesn't make sense to me, sorry. 😄 Anyway, I really write this with the best intention so you will understand why it feels strange to me. |
I see. In the future could you make that clearer when closing the bug. Your followup statements did not reveal that you had come to this conclusion and i simply thought you were going to open a new issue. I wanted to get clearer understanding of the design here before that happened. If you do want to continue pursuing something here, please provide more detail in the future to help things go more smoothly. Thanks! |
C# should allow people to allocate temp objects which would be freed soon.
For example:
The text was updated successfully, but these errors were encountered: