Как стать автором
Обновить

Комментарии 65

Во сколько раз с OpenMP быстрее, чем без него?
Сколько было процессоров/ядер?
Ну в конкретно этом случае, при генерации Множества Жюлиа с 2048 итерациями, изображение 4096x4096 с OMP генерировалось 3.175 секунд, а без OMP 5.759 секунд на процессоре Core i3 330M с 2 ядрами и HyperThreading.

А вообще, когда я ковырял OMP и OpenCL на C, то все было как-то так:
639x349

В принципе тут разницы большой между Fortran'ом и C не будет, т.к. код тривиальный, без использования каких-то хитрых возможностей.

Но там я генерировал Мандельброта и использовал float, т.к. у меня небыло видеокарты, которая поддерживает числа двойной точности.
А OpenMP уже научился корректно использовать HyperThreading?
Честно говоря даже не знаю. Но это скорее всего проблема не самого OpenMP (спецификации), а его реализаций, а так-же работы SMT в конкретной OS.
Разумеется речь не о идеалогических недостатках OpenMP :) Просто удивило, что вы указываете на наличие гипртрейдинга в процессоре. На практике у меня всегда получалось так, что HyperThreading бывает даже замедляет работу OpenMP'шных секций и я его принудительно отключаю, если запускаю какую-то тяжелую числомолотилку.
OpenMP — это просто удобный способ создавать потоки. Про то, как они реализованы, он в общем случае не в курсе.
Сразу после того как вы научитесь корректно ставить вопросы…
Верфикации результата нет.
Может вы считаете быстро но неправильно после распараллеливания?
Мне вот не нравится что вы приватные переменные не указываете. В С lvalues не зависимые от итератора обязательно должны быть private.
Изначально и было приписано PRIVATE(x, y), только зачем? Я же их только читаю, поэтому можно и не указывать. Ну можно приличия ради, пусть по регистрам процессора раскидает.
А что до верификации… смысл? Тут задача не провести мат. расчеты, а сгенерировать «прикольную» картинку, да и текст учебный, не стоит лишний раз его усложнять.
Ну сделать программу считающую быстро и неправильно дело нехитрое. Поставьте return в мейне и всех делов. Утрирую конечно.
x и y и так приватные — это итераторы.
Так же «приватными» получатся любые array(x,y)
А вот iter, z, iter2 вы обязаны указывать как private. Иначе они не попадают в TLS, и у вас там черте что…
Я не говорю что у вас там bitwise reproducebility должно быть (совпадение md5 для двух вариантов), но валидацию делать нужно. Скажем сравнить OMPN=1 и OMPN=16 с заведомо хорошей точностью (хз сколько для этой задачи — прикиньте сами).
Оу, про iter, z и iter2 я как-то и не подумал. Просто в варианте на C они у меня локальные переменные, следовательно для каждого потока свои. На днях поищу информацию о локальных переменных в Fortran, исправлю.

Кстати говоря, в do цикле x и y автоматически private.
Непонятно зачем писать на Фортране в 2014 году, ну да ладно.

(CDABS(z) .le. 4.0_8)
Лишний квадратный корень в каждой итерации, надо сравнивать с квадратом нормы

DLOG(DLOG(CDABS(z))) / DLOG(2.0_8)! Формула для сглаживания iter-ln(log2(|Z|))
Хоть разница и несущественна, строго говоря, это log2(ln(|Z|)). Ну и CDABS(z) считается повторно (квадратный корень опять ни к чему, тк все равно берём логарифм).
Если сравнить:
REAL(z)**2 + AIMAG(z)**2

и:
CDABS(z)

Разница получится в 1 μops (в моем случае sqrtsd из SSE), на скорость это практически не влияет. По крайней мере на форе IO операций записи на диск это не заметно.

А что до того зачем писать — just for fun. Лично мне нравится ковырять различные языки программирования.
Дело не в количестве инструкций, деление и квадратный корень самые медленные арифметические операции с большой задержкой и ограниченной пропускной способностью (14-34 тактов на современных микроархитектурах, на старых ещё больше).
Для x87 FPU может быть, ибо у FSQRT latency в среднем 27, но x87 сам по себе тормознутый, т.к. там происходит куча накладных расходов, при работе с его «стековыми регистрами».

С SSE все проще, у sqrtsd latency 7-32, а так-же очень легко можно перегонять значения между XMM, памятью и регистрами процессора.

Я специально замерял, разницы в скорости не было. Время выполнение каждого варианта колебалось от 10 до 12 секунд, при 2048 итерациях и разрешении 8192. Если там и был какой-то прирост, то он съедается планировщиком процессов, IO планировщиком и скоростью записи на HDD.

Проще говоря, в данной ситуации я предпочту использовать CDABS(), т.к. в коде это выглядит элегантнее, а выигрыша никакого нет.
Для числодробилок последние версии Фортрана — самое то. Дают быстрый код, достаточно лаконичны, средства для распараллеливания в наличии да и библиотек хватает. Этакий компилируемый Матлаб.

Это не для холивара, просто мнение.
Почти все суперкомпьютеры поддерживают только C/C++/Fortran компиляторы. Лично я работал вот с этими: Jugene/Juqueen (сейчас №8 в top500), GWDG, RZG. Там других компиляторов нет.
Ну так Fortran используют из-за того, что за полвека создано очень много хороших библиотек, ну а переписывать на С это нужно потратить много времени, да и в целом не очень нужно (зачем, коли на Fortran хорошо работает).
Ну да, я об этом же. Плюс он вроде бы лучше оптимизируется и параллелится, и потому иногда быстрее, чем С, а в числодробилках это важно.
Единственное отличие Фортрана от C в плане оптимизации в том, что там нет указателей (почти) и автоматически отпадает проблема aliasing. Начиная с C99 есть restricted pointers и можно сделать так же быстро как и в Фортране.
По-моему, в фортране проще как минимум еще векторизовать циклы и операции (но я специально не занимался этим вопросом никогда). Бенчмарки, впрочем, говорят, что С может быть стабильно быстрее. Но, опять же, эти бенчмарки я внимательно не исследовал: может, там не очень эффективный код фортрана и супер-оптимизированный С. На stackoverflow есть большое обсуждение.

Впрочем, я сам для таких задач использую С++. С другой стороны, мне не кажется правильным спрашивать, зачем в 2014 писать на фортране—с тех пор, как столкнулся с миром high-performance/scientific computing.
Это заблуждение, т.к. разница между фортраном и С только в фронтенде компилятора.
А кто заставляет переписывать? Вопрос был про новый код. А существующие библиотеки никто не запрещает использовать хоть из Python. Хотя и существующее переписывают «почему-то», например ЦЕРН давно перешел с CERNLIB [Fortran] на ROOT [C++].

Популярность Фортрана в науке произошла из того факта, что он простой как три копейки (в варианте 77го года). Можно просто переписать формулу с бумажки и оно начнет считать (FORmula TRANslator всё же). Простота плюс более адекватная работа с комплексными числами — рецепт успеха.

Проблема в том что, что-то более сложное чем формулу с бумажки приходится городить с помощью ужасов типа COMMON blocks и т.д. Это попытались исправить в поздних версиях стандарта, что закономерно всё только усложнило.

Единственное преимущество Фортрана сегодня это скорость компиляции, что удобно для автоматически сгенерированного кода.
А кто заставляет переписывать? Вопрос был про новый код. А существующие библиотеки никто не запрещает использовать хоть из Python.

Так так и делают. В том-же Fortran 2003 на уровне спецификации появились способы взаимодействия с C.

Хотя и существующее переписывают «почему-то», например ЦЕРН давно перешел с CERNLIB [Fortran] на ROOT [C++].

Если не ошибаюсь, то у них там было куча legacy кода и проще было начать с нуля, ежели исправлять старое.
с помощью ужасов типа COMMON blocks

Например?
Пример чего, использования common блоков? Достаточно посмотреть на любую более-менее сложную программу на Фортране 77. Объяснять чем плохи common блоки надеюсь не надо.
Писал на 77м.
Надо. Это по-своему хорошее средство, если не злоупотреблять.
Да писать можно отлично, а вот читать и отлавливать баги уже не так весело. Объясняю: когда программа связана пачкой слабодокументированных common блоков это плохо, потому что, поменяв что-то в одном месте, нельзя быть уверенным, что не поломал в другом. Бонус: отсутствие проверки типов и возможность назвать сколько угодно разных блоков одним именем, и потом удивляться результату.

Вот отличный пример гениальной программы на Фортране, которую легче переписать с нуля чем понять как она работает code.google.com/p/a-f-d-c/source/browse/trunk/qgraf/qgraf-3.1.2.f
Ну, тут глаза вытекают еще из-за форматирования. Использовать блоки if then else endif при этом писать в стиле фортран 4-77 это сильно, конечно.

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

Вполне сродни приведению через нетипизированный указатель в других языках.

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

Это понятно. Всему свое место.
Кластеры поддерживают все подряд — им пофигу какой бинарный код исполняется. Другое дело что для стандартного MPI есть врапперы только для C/Fortran, остальное как то не прижилось.
И именно это ограничивает языковые варианты — получается кто первый встал, того и тапки.
А так это стандартный x86-64 + GNU + Linux в 99% случаев. Редкие извращения в духе MS не рассматриваем.
Поддерживаю, IMHO нужно кучу переменных внутри циклов запихивать в приват и счетчики тоже защищать от интерференции с другими потоками.
Ну и число потоков логичнее задавать переменными среды, а не явно забивать 16 потоков для двухядерной машины.
16 потоков было выбрано экспериментально для моей машины, т.к. эмпирическим путем сразу учитывается работа планировщика процессов.

А счетчики в Fortran по умолчанию PRIVATE.
Под счётчиками имел ввиду iter iter2.
Даже для процесса подбора числа потоков проще менять переменную среды, чем каждый раз перекомпилировать.
9 лет назад написал программу на Фортране: ftp.radio.ru/pub/2005/10/sintez.exe Использовал Visual Fortran 6.0, замечательный язык для математики средней и большой сложности. Все встроено, и комплексные числа и матрицы. Матрицы складываются оператором А+В, транспонирование одним оператором, сказка просто.
Вот заходил сюда через буквально минут пять после появления поста — и ожидал таки легкого налёта холивара в комментах.
Я вот сейчас веду спецкурс-углубление в численные методы у физиков-теоретиков и гидродинамиков. Так вот, курс этот в основном идёт на фортране-90. Тем не менее, есть люди, пишущие на С, или С++, и видно, что им приходится тратить гораздо больше времени на реализацию и отладку разных вещей, которые в фортране «из коробки» делаются одной командой и быстро. Работа с массивами высоких размерностей без необходимости запутываться в указателях, их сечения, произвольная индексация как в статике, так и в динамике, встроенные функции для самых разных математических и справочных операций с ними, шустрые математические функции для целых, действительных и комплексных чисел, отличающиеся в коде только одной буквой в идентификаторе, и масса других мелочей, которые оставляют фортрану лидерство при выполнении расчётов как по простоте написания, так и по скорости простейшего кода. Фортран прекрасно справляется с тем, для чего был создан, и прекрасно подходит людям, для которых он был создан — они о другом думают, а не об оптимальности кода, иерархии классов и создании-разыменовывании указателей.
Фортран жив!
boost, GNU Scientific Library… да даже STL умеет сечения массивов делать. Докатимся до того, что реализацию метода контрольного объема будем из Патанкара на фортране перенабирать. Ну а отличать функции по буковке, в то время как в C++ это делает компилятор… неужели фортран — настолько вкусный кактус?
А да, ViennaCL забыл. Реализует матрицы-векторы-решатели СЛАУ на GPU через OpenCL
Ретроград вы…
Фортран конечно жив, однако делать новые проекты на нем как минимум странно.
Современный С++ дает неплохие инструменты для тех же указателей, на чем писать дело в основном вкуса.
И вообще я обожаю допиливать программы после физиков теоретиков — там не паханное поле для оптимизаций :)
Согласен, после Фортрана вынужден был перейти на Делфи, потом на С, т.к. в Фортране плохо с инструментами для работы с периферией, обработкой данных от «железа». Было с чем сравнивать, с моей точки зрения для сугубо математики Фортран самый удобный в использовании.
Вы странные вещи говорите.
Если отложить в сторону «какой кому синтаксис нравится». Чем тот же Си лучше Фортрана при работе с периферией?
Я имею в виду — все равно все через библиотеки внешние идет. И нет никакой разницы — подключить библиотеку к Си или к Фортрану.
Нужно вам, например, с драйвером пообщаться в Win32. Вы вызываете DeviceIoControl из kernel32.dll. Какая разница, lib со stub'ами к Си прилинковать или к Фортрану?
Если отложить синтаксис, суть вопроса теряется, потому как язык и есть синтаксис. А семантика — его стандартная библиотека.

При работе с периферией очень нужны лаконичные побитовые операции. в C++ есть битовые поля, в C — целая пачка операторов и циклы по произвольной операции, например, по удвоению:
for(uint8_t i=1;i<8;i=i<<1)


В фортране это конечно тоже есть, но оно менее лаконично, сравним:

const uint_8t res=a | b | c | d;

и
RES=OR(A (OR(B, OR(C,D) ) ) )

Получился прекрасный забор из скобок

Ну и фортрановские указатели являются менее гибкими.
Если отложить синтаксис, суть вопроса теряется, потому как язык и есть синтаксис. А семантика — его стандартная библиотека

Отнюдь.
Я имею в виду не средства, встроенные в язык, а способ записи;

Получился прекрасный забор из скобок

Верно.
И что мы показали? Что все языки так или иначе позволяют достучаться до периферии? Позволяют.
Только реализовывать эту возможность на фортране эквивалентно езде на велосипеде без педалей — неудобно. И чревато травмами.
Не считая приведенного примера с bitwise не вижу особых проблем. Не неудобно. Непривычно после того же C.
Не использовал Win32. В Visual Fortran 6.0 возможность создавать проекты в Win32 существовала, даже попытался что-то там сделать, но бросил, написал все ручками, все эти окна-кнопки, так мне показалось проще. Их немного требовалось, а там и чисто по математике хватало над чем голову поломать. У меня есть сомнения, что используя Win32 можно работать с периферией в режиме реального времени, как в микроконтроллерах.
А что насчет адресной арифметики, ассемблерных вставок, типов (ну в C это модификатор) наподобие volatile?
Да и в C гораздо удобнее работать с бинарными данными, включая IO-операции, ежели в Fortran. Я лично в этом убедился на том маленьком коде в статье.

Если целесообразность использования Fortran в мат. задачах еще можно оправдать, то превосходство в низкоуровневом программировании C сомневаться сложно. Может в Fortran'е и подобные задачи можно решать, но во некоторых моментах придется много «костылей» и «велосипедов» городить.
А что насчет адресной арифметики

Можно заменить другим.

ассемблерных вставок

100 лет назад, когда писал на фортране, связка ассемблер+фортран+линкер вполне работала.

наподобии volatile?

Речь же не о написании драйверов.

Я лично в этом убедился на том маленьком коде в статье.

Какой именно части? Что вам кажется неудобным?
Можно заменить другим.

А можно узнать чем можно заменить адресную арифметику? Только без костылей, чтоб было так-же удобно.

100 лет назад, когда писал на фортране, связка ассемблер+фортран+линкер вполне работала.

А каким образом вы линкером вставите ассемблерный код посреди кода на Fortran'е? Что-то вроде этого:
#include <stdio.h>

int main(void) {
	//Меняем переменные местами с помощью инструкции x86 процессора
	int a = 0xAABBCCDD, b = 0xFFFFFFFF;
	__asm__
	(
		"xchgl %[a], %[b]\n\t"
		: [a]"+r"(a), [b]"+r"(b)
	);
	printf("%x\n%x\n", a, b);

	//Меняем байты местами с помощью инструкции циклического сдвига x86 процессора
	short int c = 0xAABB;
	__asm__
	(
		"rorw $8, %[c]\n\t"
		: [c]"+r"(c)
	);
	printf("%hx", c);
}

Примеры, конечно, уровня Hello World, но в вашем случае это можно сделать только путем вызова функции, а это лишние действия по её вызову. Да и когда требуется вызвать одну инструкцию, городить целую функцию это слишком.

Речь же не о написании драйверов.

Речь шла о работе с устройствами, что из той-же оперы.
А можно узнать чем можно заменить адресную арифметику? Только без костылей, чтоб было так-же удобно.
В Фортране 77 адресная арифметика эмулируется массивами и equivalence оператором, только программа при этом становится абсолютно нечитаемой.
только программа при этом становится абсолютно нечитаемой

О том и речь. Эмулировать или извращаться можно на любом языке, только это плохо, поэтому в расчет не берется.
Именно икваленс и массив я и имел в виду.
Эмулировать или извращаться можно на любом языке

Это не извращение. Это другой способ выполнить ту же задачу.
Вот когда-то давно видел, как на Visual Basic перегоняли из бинарной строки 4 байта в integer путем прохода циклом с получением ASCII кода и умножением-сложением — вот это извращение.
А представить поле данных как массив или структуру — просто другой метод работы с данными.
Речь шла о работе с устройствами, что из той-же оперы.

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

Примеры, конечно, уровня Hello World, но в вашем случае это можно сделать только путем вызова функции, а это лишние действия по её вызову

Функцию, да.

Да и когда требуется вызвать одну инструкцию, городить целую функцию это слишком.

Так одна инструкция — предельный случай. Для обмена, емнип, есть встроенная функция swap. Байты можно поменять местами через тот же equivalence.
Насчет вставок думал, но все равно же пришлось бы С или ассемблер изучать, а обработка в следующий раз требовалась уже не настолько заковыристая, так что пришлось Фортран оставить. Хотя пытался, да :) Товарищ мне даже подпрограмму написал на ассемблере для работы с портом, попытался ее туда приделать, но решил в конце концов что это не удобно и если работать будет плохо, то причину не найдешь. То что С для работы с бинарными данными и для побитовых операций вне конкуренции, сомнений не вызывает.
Да не, по большому счету я согласен, что Фортран не так удобен для работы с аппаратурой — не тот инструмент просто.
Но все то же сделать можно, пусть и непривычным путем, кмк.

То что С для работы с бинарными данными и для побитовых операций вне конкуренции, сомнений не вызывает.

Тот же Delphi имеет такой же функционал по этой части.
Да, Delphi тоже в этом смысле неплох, но С сейчас это уже просто какой-то стандарт, очень много для него написано и есть в открытом доступе. К тому же здесь в конторе программистов на Паскале вообще уже не осталось, в случае если быстро надо вопрос некому задать.
А при чем тут микроконтроллеры? Вы же говорите о переходе сперва на Delphi, т.е. судя по всему, не о МК.
У меня есть сомнения, что используя Win32 можно работать с периферией в режиме реального времени

Естественно. Win — не rtos.
Мне нужно было с аудиокарты данные получать, делать преобразование Фурье, совершать какие-то манипуляции с составляющими, делать обратное преобразование и выдавать обратно на аудиокарту — и все это с минимальной задержкой. Я нашел в интернете уже готовый код для получения и вывода аудиоданных на Паскале и сделал все на Дельфи. Микроконтроллеры это просто для сравнения, хотя современные микроконтроллеры уже могут решать такие задачи.
Мне нужно было с аудиокарты данные получать, делать преобразование Фурье, совершать какие-то манипуляции с составляющими, делать обратное преобразование и выдавать обратно на аудиокарту — и все это с минимальной задержкой

Эквалайзер?

В Фортране, если я правильно помню, есть быстрые библиотечные реализации дискретных FFT (Intel FC).
и сделал все на Дельфи

Так если на Дельфи написано, то все равно через Win интерфейс идет работа. Не напрямую же с аппаратурой.
Перестаиваемый фильтр. Дельфи это среда просто, в которой все делалось, пользовательский интерфейс оттуда, а код работал с аппаратурой через буфер без заметных временных задержек. Хотя и не непосредственно с ЦАП-АЦП на карте, но достаточно быстро.
Раз через буфер, значит есть драйвер, т.е. язык в принципе не важен.
Ну для Фортрана я в интернете кода не нашел :)
Пытался на фортране dll написать по аналогии с примером на C. Заколебался просто, еле-еле работающий скелет осилил, но дальше терпения и знаний уже не хватило. Пример — это пользовательская библиотека для Mathcad. Смотрю на код и диву даюсь… уже ничего из написанного сам не понимаю.

Даже в самом Mathcad'е не стали так извращаться, а в примерах рекомендовали использовать фортран-код через посредников на С.

Может подскажите реальные книжки по написанию на фортране кода под нативный WinAPI? Фик с ним, с интерфейсом, хотя бы что-нить про связку с сишными программами через dll. Нужны аналоги типов, структур и пр.
Вот спасибо, добрый человек, хоть что-то, а то я по сусекам соскребал и методом проб и ошибок пытался понять как оно работает. Pdf'ина впечатляет, вроде то, что нужно. Мне и сложные структуры, и указатели, и работа со строками как раз нужны.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории