Results 1 to 3 of 3

Thread: When exactly is FlushInstructionCache needed?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    When exactly is FlushInstructionCache needed?

    I know that it's supposed to be used, whenever you use self-modifying code, as it's likely that code that has already been run will be stored in the CPU's instruction cache. The first time code gets executed, the CPU stores that code in its instruction cache, for faster execution later (if the function containing the code is executed again). But what about code that has not yet been executed? Lets say in your program you have a placeholder for code to go, that does not get executed at all. Then after the intended code is written to that memory location it is executed. That way, it won't be run, not even once, until the intended code has been written to it. Does that guaranty that the old code does not get cached (the code hasn't been executed yet), or does Windows's process of loading an EXE file into memory also cause all of that EXE file's code to be cached by the CPU?

    If I'm using a placeholder for code, and then write that code to the placeholder, before executing it, do I still need to call FlushInstructionCache? Or can I avoid using it in a situation where the CPU should not have cached the instructions (the code hasn't even been executed yet) prior to writing the intended code to that memory location?
    Last edited by Ben321; Jun 18th, 2017 at 03:29 AM.

  2. #2
    Frenzied Member
    Join Date
    May 2014
    Location
    Central Europe
    Posts
    1,372

    Re: When exactly is FlushInstructionCache needed?

    i do not think that there is a General rule apart from what you already know: "call it when using self-modifying code".

    The reason is that different CPUs have different Caching capabilities and logics so you cannot predict if the block of Memory that was modified is already cached or not. i would think that in most use cases it is not required unless you modify Memory that is within a short range of the IP and that would have been executed if no modification would have taken place. todays CPUs use alot of prediction logic in the Pipeline to determine what gets cached and Cache Memory grows with each Generation. to be safe you'd better include a call to FlushInstructionCache (or Refrain from self modifying code at all - i myself had not used this since 20yrs+ and never really missed it although it would have solved some Problems very elegant but it is also a nightmare to debug...)

    To rectify some of your expressed thoughts as far as i know it:
    the CPU does not Cache/remember already executed code. instead instructions are prefetched and cached by analysing the pipelined code and making predictions of the outcome to determine what Bytes Need to be fetched as they will be executed next. So it is also not correct that an executable is cached when loaded.
    i'd think that any API call causes the fetching logic to Cache the Bytes stored at the target address of the call and thus inserting propably a large block of Memory in the Cache in between the IP and the code after the API call. depending on the Cache size this could already be enough to ensure that the block after the call is not cached until towards the ret of the API.

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    Re: When exactly is FlushInstructionCache needed?

    Quote Originally Posted by digitalShaman View Post
    i do not think that there is a General rule apart from what you already know: "call it when using self-modifying code".

    The reason is that different CPUs have different Caching capabilities and logics so you cannot predict if the block of Memory that was modified is already cached or not. i would think that in most use cases it is not required unless you modify Memory that is within a short range of the IP and that would have been executed if no modification would have taken place. todays CPUs use alot of prediction logic in the Pipeline to determine what gets cached and Cache Memory grows with each Generation. to be safe you'd better include a call to FlushInstructionCache (or Refrain from self modifying code at all - i myself had not used this since 20yrs+ and never really missed it although it would have solved some Problems very elegant but it is also a nightmare to debug...)

    To rectify some of your expressed thoughts as far as i know it:
    the CPU does not Cache/remember already executed code. instead instructions are prefetched and cached by analysing the pipelined code and making predictions of the outcome to determine what Bytes Need to be fetched as they will be executed next. So it is also not correct that an executable is cached when loaded.
    i'd think that any API call causes the fetching logic to Cache the Bytes stored at the target address of the call and thus inserting propably a large block of Memory in the Cache in between the IP and the code after the API call. depending on the Cache size this could already be enough to ensure that the block after the call is not cached until towards the ret of the API.


    Ok. I see. I had assumed that the CPU had probably cached only the last several already executed instructions, like a shift register, and shifted them out as new ones were shifted in, with the purpose being that if new code matched code in the most recently previously executed it would be able to execute faster (performing the same operation repeatedly, such as code in a loop, would be optimized because the code in the loop would be reused from the cache, making it faster than loading it in from memory).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width