LINUX.ORG.RU

c++ gsl don't stay close to hardware

 , ,


0

4

Просто посмотрел тот же самый луп старым способом или при помощи ново рекомендуемого array_view

int sum(int * arr, size_t size)
{
	int result = 0;
	for (int i = 0; i < size; ++i)
		result += arr[i];
	return result;
}

vs

int sum(gsl::array_view<int> arr)
{
	int result = 0;
	for (int & i : arr)
		result += i;
	return result;	  
}
превращается в
	push	ebx
	push	esi
	push	edi

	xor	edi, edi
	mov	ebx, ecx

	xor	esi, esi
	npad	7
$LL4@sum:

	add	edi, DWORD PTR [ebx+esi*4]
	inc	esi
	add	esp, 8
	cmp	esi, 7
	jb	SHORT $LL4@sum

	mov	eax, edi
против
	push	ebp
	mov	ebp, esp
	push	ecx

	mov	eax, DWORD PTR _arr$[ebp]
	mov	ecx, DWORD PTR _arr$[ebp+4]

	push	ebx
	push	esi
	push	edi

	xor	edi, edi

	lea	ebx, DWORD PTR [eax+ecx*4]
	mov	esi, eax
$LL37@sum_arr:

	cmp	esi, ebx

	je	SHORT $LN3@sum_arr

	cmp	esi, eax
	jb	SHORT $LN56@sum_arr
	lea	eax, DWORD PTR [eax+ecx*4]
	cmp	esi, eax
	jae	SHORT $LN56@sum_arr

	add	edi, DWORD PTR [esi]
	mov	ecx, DWORD PTR _arr$[ebp+4]
	add	esp, 8
	mov	eax, DWORD PTR _arr$[ebp]

	add	esi, 4

	jmp	SHORT $LL37@sum_arr
$LN56@sum_arr:

	call	DWORD PTR __imp__terminate
$LN81@sum_arr:
$LN3@sum_arr:

	mov	eax, edi
Сори за интел синтакс, был доступ только к MSVC.

Компу нужно намного дольше работать чтоб получить тот же результат.

P.S. всяким адептам кричащим «c++ с классами это не c++» не лезьте сюда в тред


был доступ только к MSVC

вот тут собака из зарыта. Лучше потестить на gcc/clang с -03.

anonymous ()
Ответ на: комментарий от anonymous

apple clang-700.1.76

sum(gsl::array_view<int>):
    pushq   %rbp
    movq    %rsp, %rbp
    xorl    %eax, %eax
    testq   %rsi, %rsi
    je      .L1
    leaq    (%rdi,%rsi,4), %rcx
    shlq    $2, %rsi
    xorl    %eax, %eax
    movq    %rdi, %rdx
.L0:
    cmpq    %rdi, %rdx
    jb      .L2
    cmpq    %rcx, %rdx
    jae     .L2
    addl    (%rdx), %eax
    addq    $4, %rdx
    addq    $-4, %rsi
    jne     .L0
.L1:
    popq    %rbp
    retq
.L2:
    callq   __ZSt9terminatev
mix_mix ★★★★★ ()

Это из-за их странного fail_fast, который нельзя выключить. Если всё-таки это сделать, то GCC сгенерит одинаковый код для обеих функций.

const86 ★★★★★ ()

clang version 3.5.0-10

.LBB0_7:                                # %vector.body
                                        # =>This Inner Loop Header: Depth=1
        vpaddd  ymm0, ymm0, ymmword ptr [rdx - 224]
        vpaddd  ymm3, ymm3, ymmword ptr [rdx - 192]
        vpaddd  ymm2, ymm2, ymmword ptr [rdx - 160]
        vpaddd  ymm1, ymm1, ymmword ptr [rdx - 128]
        vpaddd  ymm0, ymm0, ymmword ptr [rdx - 96]
        vpaddd  ymm3, ymm3, ymmword ptr [rdx - 64]
        vpaddd  ymm2, ymm2, ymmword ptr [rdx - 32]
        vpaddd  ymm1, ymm1, ymmword ptr [rdx]
Код без классов векторизируется g++ и clang, а код с классами не векторизируется clang, и не компилируется g++.

userd ()

был доступ только к MSVC.

Есть 100500 (больше трех точно) онлайн компиляторов. Один из них точно выдает ассемблерный код.

Низачет, в общем, отмазка не проканала.

anonymous ()

gsl::array_view<T> имеет обязательную проверку на выход за границы массива. У большинства C++ коллекций этой проблемы нет - там есть operator[] без проверок и at() с проверками.

anonymous ()

За безопасность всегда нужно чем-то платить. Вот вы, например, стараясь показать, насколько старый for быстрее модного и молодежного range-for в паре с gsl::array_view, допустили ошибку: у вас счетчик цикла int, тогда как должен был бы быть size_t. Т.е. если натравить вашу реализацию sum(arr,size) на действительно большой массив данных, то произойдет какая-нибудь херня.

Тогда как в варианте с range-for этой ошибки нет в принципе.

Не нужно так же упускать из виду, что gsl штука новая, пока что совершенно ортогональная компиляторам. Кто знает, может через пару тройку лет, когда заточенные под конкретный компилятор версии gsl будут идти сразу вместе с компиляторами, этот range-for по array_view будет разворачиваться компиляторами в точно такой же код, как и для старого for-а.

Пока же любители старого «C with classes» вполне могут использовать array_view, например, вот так:

int sum_view_2(const array_view<int> arr)
{
	int result = 0;
	for(size_t i = 0; i < arr.size(); ++i)
		result += arr[i];
	return result;
}
(GCC 5.2.0 строит для него, навскидку, такой же код, как и для версии для вашей версии sum(arr,size)).

При этом вы защищаетесь от детских ошибок вида:

int data[] = {1, 2, 3, 4, 5, 6};
int s = sum(data, sizeof(data));

eao197 ★★★★★ ()
Ответ на: комментарий от andreyu

Спасиб, я знаю. Но туда нельзя запихать array_view, а я хотел чтоб был один и тот же компайлер для обоих примеров

CyberK ()
Ответ на: комментарий от CyberK

По-моему, гораздо лучше сначала сделать правильно, а потом заставить правильно работающую программу работать быстро. Чем написать сначала быстрый код с багами, а потом их старательно вылавливать.

Ну и, как показано выше, array_view не лишает вас возможности писать быстрый код. Так что тут ваше право — учиться ли и использовать вещи, которые мешают отстреливать ноги, или же продолжать писать как в середине 80-х, утешая себя тем, что код ну очень близко к железу.

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

У нас с вами разные области работы. Мне намного важнее быстрые итерации компиляции проекта, и каждый сьекономленый байт и такт cpu в рантайм. А все потенциальные ошибки, для етого есть множество постояно сканирююших код статик аналаьзеров, все варнинги ставятся как ошибки, дикое количество тестов и симуляторов - как железных так и программных.

И из опыта, очень очень тяжело оптимизировать программу до того уровня что требуется мне на работе не планируя перформанс с самого начала.

И вдобавок у нас есть 4 уровня человеческих QA, которые пол года проверяют всё что только можно до того как код пойдёт в продакшен.

Хотя с другой стороны, есть люди пишушие на c++ которым которым пофиг на перформанс, если всё что они делают это интеракция с пользователем, а он может и подождать не заметив до 200 мс. И они да могут позволить себе оптимизировать только те участки которые уж совсем тормозят и вылезают в профайлерах.

CyberK ()
Ответ на: комментарий от CyberK

Отлично, у вас есть возможность платить дорого за быстрый код. Я бы даже сказал возможность платить очень дорого.

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

C++ позволяет делать и то, и другое. Более того, в C++ добавляются как вещи, которые сказываются на потреблении ресурсов, так и вещи, которые не сказываются. Более того, тот же array_view можно использовать и так, и эдак. Получается, что он повышает устойчивость кода к ошибкам без повышения расходов ресурсов в рантайме, если его правильно готовить. Но за счет большей нагрузки на компилятор.

Посему не понятно, к чему вы затеяли эту тему. Вы призываете забить на array_view и обходиться старыми приемами?

Отлично. Есть области, где это оправдано. (Было бы, правда, еще лучше, если бы в стартовом сообщении вы не допустили дурацкую ошибку.)

Что делать тем, кто не готов платить за разработку столько же, сколько платите вы? Следовать вашим советам или что?

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

Вы призываете забить на array_view и обходиться старыми приемами?

А когда он появится в стандарте? Что он вообще из себя представляет?

andreyu ★★★★★ ()
Ответ на: комментарий от eao197

Ничего не делать, пусть каждый пишет что он хочет и как он хочет. Что вы вообще хотите от етого поста?

И вообще я просил вас не заходить в тред.
Секция P.S. была специально написано лично для вас и asaw. (Я даже его не выделяю здесь чтоб ненароком его не вызвать)

Здесь был только информативный пост и несколько информативных ответов. Вы же пришли и начали зачем то орать и спорить.

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

CyberK ()
Ответ на: комментарий от eao197

Вы призываете забить на array_view и обходиться старыми приемами?

Мне кажется, или предлагалось отключать в array_view проверки в релизе?

SystemD-hater ()

А кстати посаны, заметил, что если везде где можно явно ставить const, генерируемый gcc код значительно сокращается, даже если уже использовалось -O2/-O3/-Os. Я думал компилятор сам может разбирать, где переменные не изменяются в процессе выполнения.

anonymous ()
Ответ на: комментарий от CyberK

URL->Новая библиотека от майкрософт и стауструппа. для улучшения качества кода.

Это прекрасно, но когда я смогу это использовать в кроссплатформенной разработке?

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Вроде как в стандарт его даже не планируют пока добавлять. Посмотреть на то, что из себя представляет GSL, включая array_view, можно здесь. Там много шаблонной магии на данный момент, подозреваю, со временем будет больше.

eao197 ★★★★★ ()
Ответ на: комментарий от SystemD-hater

Мне кажется, или предлагалось отключать в array_view проверки в релизе?

ХЗ. Вообще пока не понятно, в каком состоянии эта библиотека — в активной разработке и может поменяться в любой момент или же она уже стабилизирована и может использоваться в продакшене.

Вроде где-то Страуструп говорил, что GSL от Microsoft это просто reference implementation и хорошо было бы иметь еще несколько разных реализаций, где интерфейс классов был бы одинаковым, а реализации разные (как это сейчас с STL-ем происходит).

Но тут вопрос в другом: действительно ли компиляторы range-for не могут раскрыть из-за особенностей array_view или же такая беда с range-for для любых кейсов с итераторами.

eao197 ★★★★★ ()
Ответ на: комментарий от andreyu

но когда я смогу это использовать в кроссплатформенной разработке?

На свой страх и риск прямо сейчас, как с любой 3rd party library. Там вот такой список компиляторов и платформ задекларирован:

  • Windows using Visual Studio 2013
  • Windows using Visual Studio 2015
  • Windows using Clang/LLVM 3.6
  • Windows using GCC 5.1
  • GNU/Linux using Clang/LLVM 3.6
  • GNU/Linux using GCC 5.1
  • OS X Yosemite using Xcode with AppleClang 7.0.0.7000072
  • OS X Yosemite using GCC-5.2.0
  • FreeBSD 10.x with Clang/LLVM 3.6
eao197 ★★★★★ ()
Ответ на: комментарий от CyberK

Ничего не делать, пусть каждый пишет что он хочет и как он хочет. Что вы вообще хотите от етого поста?

Хочу понять, какую цель вы преследовали, создавая данную тему. Возможно, вы просто не слышали про «закон дырявых абстракций», это бы многое объяснило.

И вообще я просил вас не заходить в тред.

Довольно странные ожидания при создании темы на публичном дискуссионном ресурсе.

Вы же пришли и начали зачем то орать и спорить.

Полноте, сударь, не было такого. Было указано, что есть способы использования array_view, которые не приводят к оверхеду в рантайм. Но при этом array_view продолжает защищать программиста от неприятных ошибок, вызванных невнимательностью. После чего возникло непонимание назначение данной темы. Отсюда и вопросы.

eao197 ★★★★★ ()
Ответ на: комментарий от CyberK

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

unt1tled ★★★★ ()
Ответ на: комментарий от anonymous

А кстати посаны, заметил, что если везде где можно явно ставить const, генерируемый gcc код значительно сокращается, даже если уже использовалось -O2/-O3/-Os.

Ещё можно много интересных вещей заметить если точно так же ставить noexcept.

mashina ★★★★★ ()
Ответ на: комментарий от eao197

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

anonymous ()
Ответ на: комментарий от CyberK

чоткие посоны сразу на ассмблере пишут

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.