Bus Terminal Case Study

0 views
Skip to first unread message

Jenifer Griffard

unread,
Aug 4, 2024, 10:29:39 PM8/4/24
to productefli
Ibuilt the solution then launched the Visual Studio Profiler. You can go to Debug > Performance Profiler, but I like to launch it with Alt+F2 as a shortcut. The profiler then prompts you to choose what you want to investigate: CPU, GPU, memory, etc.

That view is not very useful yet, but we can expand the callstack to look for where these come from in our code. Expanding out several nodes in RtlUserThreadStart where the vast majority of the allocations are to look for something interesting, I see this:


A std::deque will allocate every time an element is inserted into it. By contrast, a std::vector internally maintains an array. So in this case when we initially set up the TextBuffer::_storage, we insert 9,001 ROW objects into it. This results in the ROW constructor running 9,001 times as well as 9,001 allocations inside of the std::deque.


For Windows Terminal, I decided to use the implementation in boost called boost::container::small_vector. With a small_vector, you can specify the type for it to hold (just like std::vector), and you also specify how many elements it should reserve space for. Because I know most ROW objects have just a single TextAttributeRun, I replaced this line in AttrRow.hpp:


After adjusting some build files to allow the right boost header to be located, I began to hit problems with small_vector not being exactly the same as vector. Instead of calling push_back, I needed to call emplace_back in a few places and this was a good time to sprinkle in a bit of noexcept because small_vector makes more guarantees about when it can and cannot throw compared to vector. All the changes in AttrRow.cpp, AttrRow.hpp, AttrRowIterator.cpp and AttrRowIterator.hpp can be seen in the Pull Request for the full change.


With that discovered, it looked like we could use the same playbook as before and see if std::vector could be replaced with a small_vector. I switched back to Release builds to have comparable numbers with the earlier traces now that I know where to focus attention. Looking at CharRow and that vector of CharRowCell suggests another opportunity to change to a boost::container::small_vector to place the initial storage into the CharRow instance, thus avoiding another allocation per row. So, I changed the _data member from this:


At this point it looks like the allocation reduction well is drying up, so this case study will stop here. The final Pull Request included a few other small changes that helped with memory usage and CPU usage a bit, but those are outside the scope of this case study.


But seriously, I want to extend my thanks to the Windows Terminal team for asking good questions during the Pull Request process and helping shepherd my change in to ultimately being accepted. You can see the results of this change in Windows Terminal 1.6 and later, and the changes also flowed back into the Windows 11 version of conhost.exe.


Hopefully this provides some ideas on strategies for reducing memory allocations in your codebase and shows how to use the very nice Visual Studio memory profiling tools to zero in on interesting problems.


The site is secure.

The ensures that you are connecting to the official website and that any information you provide is encrypted and transmitted securely.


Terminal lucidity, the unexpected return of mental clarity and memory shortly before the death of patients suffering from severe psychiatric and neurologic disorders, has raised the curiosity of numerous physicians and laypersons in the past. However, this peculiar phenomenon has received little attention in the recent decades. In previous publications, we have presented overviews of cases of terminal lucidity in various neurologic and psychiatric disorders. In this article, we highlight terminal lucidity in persons with mental disabilities, and focus on one of the most remarkable cases that have been reported. We provide biographical background information about the two principal witnesses who reported this case. It concerns the death of Anna Katharina Ehmer, a 26-year-old woman with severe mental disabilities who lived in an institution for people with mental disorders, and who had allegedly never spoken a single word during her life. Yet, she was reported to have sung dying songs for a half hour before she died. The case was reported by the head of this institution and by its chief physician. We consider it difficult to evaluate the authenticity of the case definitively in retrospect. Nevertheless, there are similar cases and a variety of other anomalous brain-related findings we consider worth investigating. Studies into such anomalous cases might improve our concepts of human brain functioning and of mental processing in persons with mental disabilities, and might be of special value for the dying, the bereaved, and caretakers.


The situation is different on other mainstream OSes. For example, Go used to do"raw system calls" on macOS, but Go programs often broke with new kernel versions. As ofGo 1.16, they've switched tolibc.


Wrong! It absolutely is not zsh. First, it's my Logitech K120 keyboard, which Ikeep trying to replace but is the only thing that has worked for me for the pastdecade, that's right mechanical keyboard nerds, your resident deep dive writeris using second-rate office supplies.


Wrong! Because that would not be a TTY. If zsh's standard input was merely apipe that Windows Terminal wrote to (let's forget there's two different OSesin action for a minute), isatty would definitely return false.


I don't really think we need to care about ioctls either, if all we want to dois just pretend we're a terminal - we don't need to get the terminal info, ourchild process does... just like zsh requests the terminal info set by WindowsTerminal.


If it successfully finds one, it subsequently changes the ownership of the secondarydevice to the real UID of the current process, the group membership to the group"tty" (if such a group exists in the system), the access permissions for readingand writing by the owner, and for writing by the group, and invalidates anycurrent use of the line by calling revoke(2).


Because see, Linux processes have, like, "sessions", and those sessions have"leaders" and also they have a "controlling terminal" and there's definitely acall to "allocate a new session" but the way you change the "controllingterminal" is much much funnier.


In the child process, it returns 0, and that's how you know it's the childprocess because, well, since it's an "exact" copy, they're still executing thesame code at this point. So you compare against 0, and things diverge fromthere.


And usually, at that point, you want to move on to exec, which asks the kernelto violently replace the current process (the child process we just fashionedfrom the ribs of Adam the memory space of the calling process) withwhichever ELF file we said to use.


Well. If we call it before fork it's going to mess with our parent process,which is almost definitely not what we want. We don't want to become the leaderof our session. We don't want to change our own controlling terminal.


This closure will be run in the context of the child process after a fork.This primarily means that any modifications made to memory on behalf of thisclosure will not be visible to the parent process. This is often a veryconstrained environment where normal operations like malloc, accessingenvironment variables through std::env or acquiring a mutex are not guaranteedto work (due to other threads perhaps still running when the fork was run).


This also means that all resources such as file descriptors and memory-mappedregions got duplicated. It is your responsibility to make sure that the closuredoes not violate library invariants by making invalid use of these duplicates.


Panicking in the closure is safe only if all the format arguments for thepanic message can be safely formatted; this is because although Command callsstd::panic::always_abort before calling the pre_exec hook, panic will still tryto format the panic message.


However, amos has a use case where he wants to re-use the terminal for spawningseveral processes in sequence, yet needs to tell apart the output from eachindividual process, so it makes sense for him. In most other cases though, youcan just close the parent's secondary fd and be done with it!


First, Maya actuallydid the exercise left to the reader and figured out why the async/tokio versionwas hanging at the end of "main". It is a very interesting read, and it showcasesthe new and still-experimental tokioconsole.


Second, a whole bunch of folks mentioned that there are ways other than ioctlsto, for example, tell terminal size.Apparently you canmove the cursor to the bottom right corned, write \e[6n to stdout and it willreply with the cursor position. For xterm-compatibleterminals, youcan send \e[18t and they'll reply with \e[8;rows;colst, and you don'teven have to move the cursor!


Imagine being the head of a Facilities Management group that has maintained a particular facility for almost 50 years and being told that the entire facility is being replaced. Literally, every system and asset you have grown to know, understand, and maintain will be replaced by brand new systems and assets. Operational and maintenance procedures that you have developed over half a century will need to be rethought and restructured, or, at the very least, recreated for the new facility. Faced with that type of once in a lifetime organizational change, how do you ensure that you are putting your organization in the best possible position to efficiently utilize and effectively maintain the new facility?


For the new, $1.5 billion Single Terminal and Parking Garage at Kansas City International Airport (MCI), MCI applied an innovative approach to implementing asset management at the very beginning of the new terminal project. Arora Engineers (Arora), along with their wholly owned subsidiary, EDI, worked to ensure that operations and maintenance staff were in a position to use and maintain the entire new facility (the organizations most critical asset) from day one. MCI was therefore able to reduce their implementation costs by approximately 50% with a digital delivery compared to a traditional asset management implementation.

3a8082e126
Reply all
Reply to author
Forward
0 new messages