оптимизация вызова массива указателей на функции - PullRequest
2 голосов
/ 05 июля 2019

У меня есть следующий цикл, который вызывает все указатели функций в массиве:

for(auto f : program) {
   f();
}

Я хотел бы оптимизировать это.До сих пор я пробовал два метода:

  1. Хвостовая рекурсия
  2. Код JITting с резьбой

Вот полный код теста: https://coliru.stacked -crooked.com / a / d639f024b1222c54

Результаты синхронизации на моей машине (iMac Pro 8-Core):

naive: 0.530534
tail recursion: 0.265192
JIT threaded: 0.125106

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

Могу ли я сделать лучше, чем хвостовая рекурсия без JITting? (на iOS JITting не разрешен)

Обратите внимание, что функции нельзя переупорядочивать.

1 Ответ

1 голос
/ 06 июля 2019

Да. На самом деле мы можем превзойти многопоточный код без JITting.

Тестовый код состоит из 100 возможных функций. Я написал небольшую программу для генерации кода для массива функций 100x100, которые вызывают пары из этих 100 функций. Оптимизатор вводит исходные 100 в пары. Теперь у нас есть:

naive: 0.534162
tail recursion: 0.269307
JIT threaded: 0.124608
pairs: 0.085922

Этот метод может быть обобщен для реальных случаев путем анализа общих последовательностей вызовов функций вместо генерации всех возможных пар.

Это может быть объединено с хвостовой рекурсией для еще более быстрой отправки.

...