Вопросы об оптимизации компилятора

Вот мой подход старой школы:

$line = ''
Get-Content C:\test.txt | 
    Select-String -Pattern 'Backup-ID: ' ,'Policy: ' ,'Primary Copy: ' ,'Expires:  ' ,'Copy Number: ' , 'Fragment Size ' ,'Expires: ' , 'MediaID:' |
        ForEach-Object {
            $aux = 

Вот мой подход старой школы:

[110]

Вывод :

D:\PShell\SO\54921319.ps1
hostname01,VM_weekly,23,1/5/2024 3:19:13 AM,2,6188832,1/5/2024 3:19:13 AM,XXX122,3,6188832,1/5/2024 3:19:13 AM,XXX134
hostname02,VM_weekly2,24,1/5/2024 3:19:13 AM,2,6188832,1/5/2024 3:19:13 AM,XXX244,3,6188832,1/5/2024 3:19:13 AM,XXX199,4,6188832,1/5/2024 3:19:13 AM,XXX177

Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

$xArr = D:\PShell\SO\54921319.ps1
$xCsv = $xArr |  ConvertFrom-Csv -Header $(1..30|%{"a

Вот мой подход старой школы:

[110]

Вывод :

[111]
[112]

Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

[113]

Конечно, вы можете вычислить

  • фактический верхний предел для -Header $(1..30|%{"a

    Вот мой подход старой школы:

    [110]

    Вывод :

    [111]
    [112]

    Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

    [113]

    Конечно, вы можете вычислить

    • фактический верхний предел для [114] вместо оцененного 30, например. как ($xArr | % {

      Вот мой подход старой школы:

      [110]

      Вывод :

      [111]
      [112]

      Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

      [113]

      Конечно, вы можете вычислить

      • фактический верхний предел для [114] вместо оцененного [115], например. как [116],
      • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
      • [1120 ].Split(',').Count}|Measure-Object -Maximum).Maximum
        ,
      • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
      • [1120 ]"})
        вместо оцененного 30, например. как ($xArr | % {

        Вот мой подход старой школы:

        [110]

        Вывод :

        [111]
        [112]

        Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

        [113]

        Конечно, вы можете вычислить

        • фактический верхний предел для [114] вместо оцененного [115], например. как [116],
        • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
        • [1120 ].Split(',').Count}|Measure-Object -Maximum).Maximum
          ,
        • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
        • [1120 ]"}) $xcsv | Export-Csv -NoTypeInformation -Path c:\temp\result.csv

Конечно, вы можете вычислить

  • фактический верхний предел для -Header $(1..30|%{"a

    Вот мой подход старой школы:

    [110]

    Вывод :

    [111]
    [112]

    Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

    [113]

    Конечно, вы можете вычислить

    • фактический верхний предел для [114] вместо оцененного 30, например. как ($xArr | % {

      Вот мой подход старой школы:

      [110]

      Вывод :

      [111]
      [112]

      Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

      [113]

      Конечно, вы можете вычислить

      • фактический верхний предел для [114] вместо оцененного [115], например. как [116],
      • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
      • [1120 ].Split(',').Count}|Measure-Object -Maximum).Maximum
        ,
      • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
      • [1120 ]"})
        вместо оцененного 30, например. как ($xArr | % {

        Вот мой подход старой школы:

        [110]

        Вывод :

        [111]
        [112]

        Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

        [113]

        Конечно, вы можете вычислить

        • фактический верхний предел для [114] вместо оцененного [115], например. как [116],
        • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
        • [1120 ].Split(',').Count}|Measure-Object -Maximum).Maximum
          ,
        • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
        • [1120 ] -split ':',2 # only 2 substrings if ($aux[0] -eq 'Backup-ID') { if ( $line -ne '' ) { $line } # Write-Output (current line) $line = $aux[1].Trim() } else { $line += ',' + $aux[1].Trim() } } $line # Write-Output (last line)

Вывод :

D:\PShell\SO\54921319.ps1
hostname01,VM_weekly,23,1/5/2024 3:19:13 AM,2,6188832,1/5/2024 3:19:13 AM,XXX122,3,6188832,1/5/2024 3:19:13 AM,XXX134
hostname02,VM_weekly2,24,1/5/2024 3:19:13 AM,2,6188832,1/5/2024 3:19:13 AM,XXX244,3,6188832,1/5/2024 3:19:13 AM,XXX199,4,6188832,1/5/2024 3:19:13 AM,XXX177

Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

$xArr = D:\PShell\SO\54921319.ps1
$xCsv = $xArr |  ConvertFrom-Csv -Header $(1..30|%{"a

Вот мой подход старой школы:

[110]

Вывод :

[111]
[112]

Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

[113]

Конечно, вы можете вычислить

  • фактический верхний предел для -Header $(1..30|%{"a

    Вот мой подход старой школы:

    [110]

    Вывод :

    [111]
    [112]

    Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

    [113]

    Конечно, вы можете вычислить

    • фактический верхний предел для [114] вместо оцененного 30, например. как ($xArr | % {

      Вот мой подход старой школы:

      [110]

      Вывод :

      [111]
      [112]

      Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

      [113]

      Конечно, вы можете вычислить

      • фактический верхний предел для [114] вместо оцененного [115], например. как [116],
      • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
      • [1120 ].Split(',').Count}|Measure-Object -Maximum).Maximum
        ,
      • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
      • [1120 ]"})
        вместо оцененного 30, например. как ($xArr | % {

        Вот мой подход старой школы:

        [110]

        Вывод :

        [111]
        [112]

        Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

        [113]

        Конечно, вы можете вычислить

        • фактический верхний предел для [114] вместо оцененного [115], например. как [116],
        • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
        • [1120 ].Split(',').Count}|Measure-Object -Maximum).Maximum
          ,
        • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
        • [1120 ]"}) $xcsv | Export-Csv -NoTypeInformation -Path c:\temp\result.csv

Конечно, вы можете вычислить

  • фактический верхний предел для -Header $(1..30|%{"a

    Вот мой подход старой школы:

    [110]

    Вывод :

    [111]
    [112]

    Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

    [113]

    Конечно, вы можете вычислить

    • фактический верхний предел для [114] вместо оцененного 30, например. как ($xArr | % {

      Вот мой подход старой школы:

      [110]

      Вывод :

      [111]
      [112]

      Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

      [113]

      Конечно, вы можете вычислить

      • фактический верхний предел для [114] вместо оцененного [115], например. как [116],
      • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
      • [1120 ].Split(',').Count}|Measure-Object -Maximum).Maximum
        ,
      • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
      • [1120 ]"})
        вместо оцененного 30, например. как ($xArr | % {

        Вот мой подход старой школы:

        [110]

        Вывод :

        [111]
        [112]

        Редактировать: [1119 ] … мне нужно экспортировать файл CSV… .

        [113]

        Конечно, вы можете вычислить

        • фактический верхний предел для [114] вместо оцененного [115], например. как [116],
        • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
        • [1120 ].Split(',').Count}|Measure-Object -Maximum).Maximum
          ,
        • или даже вычислить несколько читаемых человеком заголовков (имея в виду повторяющиеся имена некоторых свойств для каждого Copy Number внутри данного Backup-ID)
        • [1120 ]
6
задан Mike G. 6 May 2009 в 00:26
поделиться

5 ответов

  1. Я полагаю, что многие компиляторы используют SSAPRE (устранение частичного избыточного статического одиночного назначения) для устранения повторяющихся выражений. Для этого требуется, чтобы код был в форме SSA , что позволяет проводить еще большую оптимизацию.

  2. Я не совсем уверен в этом, но посмотрите на этот список пропусков LLVM . LLVM - это оптимизирующий IR для компиляторов, который часто быстрее, чем даже GCC. Существует небольшое объяснение каждого прохода. Если вам нужна дополнительная информация, посмотрите источник LLVM для этих проходов. Он написан на C ++, но довольно чистый и понятный.

Редактировать: Кстати, если вы разрабатываете компилятор, я настоятельно рекомендую LLVM, он очень прост в использовании и генерирует высоко оптимизированный код.

3
ответ дан 8 December 2019 в 17:27
поделиться

Я бы настоятельно рекомендовал две печатные ссылки на эти темы:

  1. Усовершенствованный дизайн и реализация компилятора Стивена С. Мучника
  2. Создание оптимизирующего компилятора Роберта Моргана

Книга Мучника находится на формальной стороне, но очень удобочитаема и имеет хорошие описания всех важных методов оптимизации. Книга Моргана гораздо более практична и станет отличной основой для проекта компилятора, ориентированного на методы оптимизации. Ни одна книга не может сказать много о лексическом анализе или разборе, знание этих предметов предполагается.

5
ответ дан 8 December 2019 в 17:27
поделиться

For 1, The name of the optimization you're looking for is common subexpression elimination (CSE). Depending on your representation, this can be fairly easy. Usually, a compiler will have some intermediate representation of a program where operations are broken down as much as possible and linearized. So for example, the expression c = a * b + a * b might be broken down as:

v1 = a * b
v2 = a * b
c = v1 + v2

So you could do CSE at a very low level by looking for operations with the same operator and operands. When you encounter a duplicate (v2 in this case), you replace all instances of it with the original. So we could simplify the code above to be:

v1 = a * b
c = v1 + v1

This generally assumes that you only assign each variable once (single static assignment form), but you can implement something like this without that restriction. This gets more complicated when you try and perform this optimization across branches. As Zifre mentions, look into Partial Redundancy Elimination.

Either way, you get some basic improvement, and all you need to keep track of are basic expressions. You may want to take this a step further and look for arithmetic identities. For instance, a * b is the same as b * a. Also, x * (y + z) = x * y + x * z. This makes your optimization more complicated, and it's not clear that it would give you that much performance improvement. Anecdotally, most of the benefit from a CSE optimization comes from address computations like array accesses, and you won't need complicated identities like the ones above.

For 2, what strength reductions are useful really depends on the architecture you compile for. Usually this just involves transforming multiplications and divisions into shifts, additions, and subtractions.

5
ответ дан 8 December 2019 в 17:27
поделиться

To add one more book to the list of recommendations, check out "Hacker's Delight" by Henry S. Warren. It's a great compendium of techniques for optimizing common operations, like transforming integer divisions into multiplications.

1
ответ дан 8 December 2019 в 17:27
поделиться

Требуется устранение частичной избыточности (PRE). И CSE (из других ответов), и движение кода с инвариантным циклом относятся к PRE. (Вариантом PRE является Lazy Code Motion, которое я считаю оптимальным.)

Ознакомьтесь с конспектами лекции Кейта Купера , которые, кажется, очень хорошо описывают методы.

Делайте НЕ используйте SSAPRE. AFAIK, для этого требуется особая форма SSA, известная как HSSA, которая имеет несколько недостатков:

  • Это довольно сложно
  • Требуется глобальная нумерация значений (и поэтому SSAPRE не обеспечивает нумерацию значений, поскольку ожидается, что она уже существует ).
  • Он ничего не предоставляет, если ваш язык не поддерживает указатели на переменные стека (и если это так, прекратите писать свой собственный анализ и используйте LLVM или gcc).
  • gcc какое-то время использовал HSSA, но они отошли от этого.
  • LLVM экспериментировал с этим, но, AFAIK, они его больше не используют.

РЕДАКТИРОВАТЬ:

В книге Мучника есть подробное описание, на которое есть ссылка в другом ответе.

0
ответ дан 8 December 2019 в 17:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: