2012-05-14 1 views
1

Я создаю компилятор, который создает код C++ в массив символов, который переводится JIT-компилятором Clang в LLVM-IR, а затем далее JIT-перевод на исполняемый код (который чем выполняется).Быстро компилировать эффективный алгоритм сортировки (для компиляции JIT)

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

Теперь мой вопрос: Что такое эффективный алгоритм сортировки, который может с помощью JIT, составленный LLVM очень быстро и на то же время очень быстро при исполнении? Существуют ли где-то алгоритмы, по которым можно быстро компилировать и быстро запускать?

Моя первая идея состояла в том, чтобы просто выполнить функцию сравнения и передать ее qsort() в качестве указателя (я могу ссылаться на внешние скомпилированные функции в LLVM). Тем не менее, qsort потрясающе неэффективен во время выполнения. Альтернатива, используя std :: sort, является потрясающе неэффективной во время компиляции из-за ее шаблонов и stl-blubbla-sugar.

Я сделал некоторые тест производительности для исполнения на следующий структуры:

struct MyStruct { 
int x; 
long z; 
bool operator<(const struct MyStruct& other) const { return (x < other.x) || (x==other.x&&z<other.z); } 
} 

1MB среды выполнения данных:

  • станд :: сортировать: 5 мс
  • QSort: 14 мс
  • самописью: 6 мс

1 ГБ автономной работы данных:

  • станд :: сортировать: 8,9 s
  • QSort: 24 s
  • самоуправления написано: 10,1 с

К сожалению, я не JIT компиляции раз прямо сейчас, но опубликует их в будущем.

В настоящее время кажется, что мой собственный письменный вид лучше, чем qsort или std :: sort, но я бы предпочел использовать некоторую реализацию библиотеки.

Есть ли у вас предложения по существующим реализациям сортировки, которые бы быстро выполнялись и для компиляции? Возможно ли какие-либо другие возможности ускорить компиляцию при быстрой сортировке (только компилировать функцию сравнения или что-то в этом роде)?

Кстати, вот мой самостоятельно написал (украдено из http://alienryderflex.com/quicksort/) своего рода рутина (для JITing, я бы не стал использовать тип шаблона, но заменяя его непосредственно с пользовательского типа, в том числе «< =»):

template< typename Type > 
void self_written_sort(Type *arr, int elements) { 
    #define MAX_LEVELS 64 
    Type piv; 
    int beg[MAX_LEVELS], end[MAX_LEVELS], i=0, L, R, swap ; 
    beg[0]=0; end[0]=elements; 
    while (i>=0) { 
    L=beg[i]; R=end[i]-1; 
    if (L<R) { 
     piv=arr[L]; 
     while (L<R) { 
     while (arr[R]>=piv && L<R) R--; if (L<R) arr[L++]=arr[R]; 
     while (piv<=arr[L] && L<R) L++; if (L<R) arr[R--]=arr[L]; } 
     arr[L]=piv; beg[i+1]=L+1; end[i+1]=end[i]; end[i++]=L; 
     if (end[i]-beg[i]>end[i-1]-beg[i-1]) { 
     swap=beg[i]; beg[i]=beg[i-1]; beg[i-1]=swap; 
     swap=end[i]; end[i]=end[i-1]; end[i-1]=swap; }} 
    else { 
     i--; 
}}} 
+3

«мой собственный письменный вид лучше, чем qsort или std :: sort» - но в соответствии с результатами, которые вы опубликовали, std :: sort выиграл в обоих случаях ... –

+1

Также, хотя я могу представить, что STL * source * код может быть медленным для компиляции (из-за всего маневра шаблона/# включить), я не могу себе представить, что соответствующий IR существенно отличается от чего-либо еще с точки зрения сложности (и, следовательно, скорости JIT). Или вы говорите, что вы компилируете код исходного кода C++ * во время выполнения? –

+0

Вы уверены, что необходимо действительно скомпилировать алгоритм каждый раз (я имею в виду, а не только привязывать его каждый раз)? Если вам нужно только связать его, то сам алгоритм может быть таким же сложным (и оптимизированным во времени), как вы хотите. – dialer

ответ

2

Я бы сначала попытаться передать указатель на функцию std::sort, и, таким образом, использовать его в qsort образом:

  • сам алгоритм предкомпилированного
  • функция сравнения JITed и передается динамически

Я думаю, что он все равно будет выше qsort, потому что алгоритм будет манипулировать память осмысленно и только сравнение можно было бы назвать (на самом деле).

+0

Хорошая идея, я попробую это. Таким образом, это означает, что я также буду использовать функцию int (const void *, const void *) ptr как qsort (фактически bool (const void *, const void *), поскольку std :: sort использует только «меньше»), но передайте ее станд :: сортировка. Я опубликую номера производительности, как только я его протестирую. – eci

+0

Насколько я понимаю, причина 'std :: sort' имеет преимущество перед qsort, потому что предикат сравнения может быть встроен. –

+0

@eci: no, вы должны использовать функцию 'bool (T const &, T const &)'. Набирается C++. Кроме того, вы можете захотеть «распознать» общие компараторы и переключиться на предварительно оптимизированный код (например, для '<'). –