2 Очень быстрый непроверяющий XML-парсер, который строит DOM-дерево из XML-файла.
3 Полная поддержка Unicode с вариантами интерфейса Unicode и автоматического преобразования кодирования.
5 Тестирование
Для тестирования приложения была реализована локальная сеть из трёх персональных компьютеров. Приведем протокол взаимодействия сервера и клиента (все задания и ответы на них взяты для примера).
Вначале необходимо запустить сам сервер с корректно заполненным файлом конфигурации. Если сервер запущен, появится примерно такое окно (рисунок 5).
C:\i rig i n al\Debug\£erver,ei
л конунгурацни обнаружен, IP: 192.168.Ш.14. ORT: 22Ш12 ayUariants: C:N\ aySaweFile: C:\4 роисхадит запуск сервера ервер запцтен успешна жидание подключений
пуск предварительных настроек сервера
Рисунок 5 - Пример успешно запущенного сервера
После появления сообщения «Ожидание подключений» можно запускать клиент При успешном присоединении к серверу бордюр области регистрации (рисунок 6) будет зеленым и серым - противном случае.
Рисунок 6 - Окно регистрации
После регистрации появляется окно выбора варианта, далее пользователь попадает в основное окно клиента (рисунок 7). В левом блоке написаны номер задания и текст самого задания. Правый блок отведен под данные пользователя, ввод ответа и кнопки управления. В нижнем блоке указанно время, отведенное
на решение задания с датой тестирования. Также для ознакомления с инструкцией пользователя в правом верхнем углу присутствует меню справки с калькулятором. После завершения работы либо по истечении времени, отведенного на выполнение работы, выводятся результаты.
В настоящее время разработанные сервер и клиент находятся в стадии тестирования.
В дальнейшем планируется дополнить сервер базой данных определенным образом классифицированных и систематизированных заданий с эталонными ответами, средствами формирования вариантов заданий по определенным заранее критериям, а также генератором текстов заданий поисково-вычислительного характера.
УДК 519.688
С.О. Козлов, А.А. Медведев
Курганский государственный университет
ИСПОЛЬЗОВАНИЕ ТЕХНОЛОГИИ CUDA ПРИ РАЗРАБОТКЕ ПРИЛОЖЕНИЙ ДЛЯ ПАРАЛЛЕЛЬНЫХ ВЫЧИСЛИТЕЛЬНЫХ УСТРОЙСТВ
Аннотация. В статье приводится краткое описание технологии CUDA и рассматриваются вопросы, связанные с эффективным применением этой технологии при разработке приложений для устройств, поддерживающих параллельные вычисления.
Ключевые слова: технология CUDA, программы, параллельные вычисления.
S.O. Kozlov, A.A. Medvedev Kurgan State University
THE USE OF CUDA TECHNOLOGY WHEN DEVELOPING APPLICATIONS FOR PARALLEL COMPUTING DEVICES
Annotation. The article provides a brief description of CUDA technology and discusses the issues associated with the effective use of this technology when developing applications for devices that support parallel computing.
Keywords: CUDA technology, program, parallel computing.
Рисунок 7 - Основное окно клиентского приложения
ВВЕДЕНИЕ
Предложенная компанией Nvidia технология CUDA (Compute Unified Device Architecture) заметно облегчает написание GPGPU-приложений (GPGPU - General-Purpose computing on Graphics Processing Units). Она не использует графических API (Application Programming Interface) и свободна от ограничений, свойственных этим API.
Данная технология предназначена для разработки приложений для массивно-параллельных вычислительных устройств. На сегодняшний момент поддерживаемыми устройствами являются все видеокарты компании Nvidia, начиная с серии GeForce8, а также специализированные для решения расчетных задач видеокарты семейства Tesla.
Основными преимуществами технологии CUDA являются ее простота (все программы пишутся на «расширенном» языке С), наличие хорошей документации, набор готовых инструментов, включающий профайлер, набор готовых библиотек, кроссплатформенность (поддерживаются Microsoft Windows, Linux и Mac OS X), а также CUDA является бесплатной (ее можно скачать с сайта www.developer.nvidia.com). На момент написания статьи последней версией являлась CUDA 6.5.
Технология CUDA построена так, что GPU (называемый устройством, device) выступает в роли массивно-параллельного сопроцессора к CPU - Central processing unit (называемому host). Программа на CUDA задействует как CPU, так и GPU. При этом обычный (последова-
тельный, то есть непараллельный) код выполняется на CPU, а для массивно-параллельных вычислений соответствующий код выполняется на GPU как набор одновременно выполняющихся нитей (потоков, threads) [1].
При этом очень важно понимать, что между нитями на CPU и нитями на GPU есть принципиальные различия:
1 Нити на GPU обладают крайне небольшой стоимостью создания, управления и уничтожения (контекст нити минимален, все регистры распределены заранее);
2 Для эффективной загрузки GPU необходимо использовать много тысяч отдельных нитей, в то время как для CPU обычно достаточно 10-20 нитей.
За счет того, что программы в CUDA пишутся фактически на обычном языке C (на самом деле для частей, выполняющихся на CPU, можно использовать язык C++), в котором добавлено небольшое число новых конструкций (спецификаторы типа, встроенные переменные и типы, директива запуска ядра), написание программ с использованием технологии CUDA оказывается заметно проще, чем при использовании традиционного GPGPU (то есть использующего графические API для доступа к GPU). Кроме того, в распоряжении программиста оказывается гораздо больше контроля и возможностей по работе с GPU.
Ниже приведен пример - фрагмент кода, использующий GPU для поэлементного сложения одномерных массивов [2, 18]:
_global void sumKernel (float *a, float *b, float *c){
/*Функция-ядро для суммы двух элементов массивов Входные параметры:
1. Массив a.
2. Массив b.
3. Массив с.
int idx=trheadIdx.x+blockIdx.x*blockDim.x; c[idx]=a[idx]+b[idx];
}
void sum (float *a, float *b, float *c, int n){ int numBytes=n*sizeof(float); float *aDev=NULL; float *bDev=NULL; float *cDev=NULL;
//Выделить память на GPU. cudaMalloc ((void **)&aDev, numBytes); cudaMalloc ((void **)&bDev, numBytes); cudaMalloc ((void **)&cDev, numBytes);
//Задать конфигурацию запуска нитей. dim3 threads=dim3 (512,1); dim3 blocks=dim3 (n/threads.x,1);
//Скопировать входные данные из памяти CPU в память GPU. cudaMemcpy (aDev, a, numBytes, cudaMemspyHostToDevice); cudaMemcpy (bDev, b, numBytes, cudaMemspyHostToDevice);
//Вызвать ядро с заданной конфигурацией для обработки данных. sumKernel<<<blocks, threads>>> (aDev, bDev, cDev);
//Скопировать результаты в память CPU.
cudaMemcpy (c, cDev, numBytes, cudaMemcpyDeviceToHost);
//Освободить выделенную память CPU. cudaFree (aDev); cudaFree (bDev); cudaFree (cDev);
Хотя для массивов, расположенных в памяти GPU, применяются обычные указатели так же, как и для данных, расположенных в памяти CPU, очень важно знать то, что CPU не может напрямую обращаться к памяти GPU по таким указателям. Вся работа с памятью GPU ведется при помощи специальных функций.
Приведем основной алгоритм работы с технологией CUDA [2, 19]:
1 Выделяем память на GPU;
2 Копируем данные из памяти CPU в выделенную память GPU;
3 Осуществляем запуск ядра (или последовательно запускаем несколько ядер);
4 Копируем результаты вычислений обратно в память CPU;
5 Освобождаем выделенную память GPU.
В данной программе мы для каждого допустимого индекса входных данных запускаем отдельную нить для осуществления нужных вычислений. Все эти нити выполняются параллельно, и каждая нить может получить информацию о себе через встроенные переменные.
Во время работы программы нити разбиваются на группы по 32 нити, называемыми warp^^ Только нити в пределах одного warp'a выполняются физически одновременно. Нити из разных warp^ могут находиться на разных стадиях выполнения программы. При этом управление warp^ прозрачно осуществляет сам GPU.
Для решения задач CUDA использует очень большое количество параллельно выполняемых нитей, при этом обычно каждой нити соответствует один элемент вычисляемых данных.
Все запущенные на выполнение нити организованы в следующую иерархию. Верхний уровень иерархии -сетка (grid) - соответствует всем нитям, выполняющим данное ядро. Верхний уровень представляет из себя одномерный или двумерный массив блоков (block). Каждый блок - это одномерный, двумерный или трехмерный массив нитей (thread). При этом все блоки, образующие сетку, имеют одинаковую размерность и размер.
Каждый блок в сетке имеет свой адрес, состоящий из одного или двух неотрицательных целых чисел (индекс блока в сетке). Аналогично каждая нить внутри блока также имеет свой адрес - одно, два или три неотрицательных целых числа, задающих индекс нити внутри блока.
Для того, чтобы ядро могло однозначно определить номер нити (а значит и элемент данных, который нужно обрабатывать), используются встроенные переменные threadldx и blockldx. Каждая из этих переменных является трехмерным целочисленным вектором. Аналогично ядро может получить размеры сетки и блока через встроенные переменные gridDim и blockDim.
Подобное разделение всех нитей является еще одним общим приемом использования CUDA - исходная задача разбивается на набор отдельных подзадач, решаемых независимо друг от друга. Каждой такой подзадаче соответствует свой блок нитей.
При этом каждая подзадача совместно решается всеми нитями своего блока. Разбиение нитей на warp'bi происходит отдельно для каждого блока таким образом, что все нити одного warp'a всегда принадлежат одному блоку. При этом нити могут взаимодействовать между собой только в пределах одного блока. Нити разных блоков взаимодействовать между собой не могут.
Подобный подход является удачным компромиссом между необходимостью обеспечить взаимодей-
ствие нитей между собой и стоимостью обеспечения подобного взаимодействия - обеспечить возможность взаимодействия каждой нити с каждой было бы слишком сложно и дорого.
Существует два механизма, при помощи которых нити внутри блока могут взаимодействовать друг с другом [2, 21]:
1 Разделяемая память;
2 Барьерная синхронизация.
Каждый блок получает в свое распоряжение определенный объем быстрой разделяемой памяти, в которую все нити блока могут совместно использовать. Поскольку нити блока не обязательно выполняются физически параллельно, то для того, чтобы не возникало проблем с одновременной работой с разделяемой памятью, необходим некоторый механизм синхронизации блока.
Технология CUDA предлагает довольно простой способ синхронизации - так называемую барьерную синхронизацию. Для ее осуществления используется
вызов встроенной функции _syncthreads(), которая
блокирует вызывающие нити блока до тех пор, пока все нити блока не войдут в эту функцию. Таким образом,
при помощи _syncthreads() мы можем организовать
«барьеры» внутри ядра, гарантирующие, что если хотя бы одна нить прошла барьер, то не осталось ни одной за барьером (не прошедшей его).
1 Библиотека Thrust
Библиотека Thrust - готовая библиотека шаблонов для CUDA, реализованная на основе стандартной библиотеки шаблонов (STL) [3]. Библиотека Thrust позволяет реализовывать высоко производительные параллельные приложения с минимальными усилиями программирования. Она предоставляет богатую коллекцию параллельных примитивов, таких как scan, sort и reduce, которые можно всячески комбинировать, чтобы реализовать сложные алгоритмы с кратким, читаемым исходным кодом.
В библиотеке Thrust содержатся два вектора контейнера: host_vector и device_vector. Как можно понять из названия, host_vector хранится в памяти компьютера, в то время как device_vector хранится в памяти GPU устройства. Векторы host_vector и device_vector могут хранить данные любого типа. Также векторы host_vector и device_vector могут быть изменены динамически.
В библиотеке Thrust реализованы следующие алгоритмы: трансформация (Transformations); редукция (Reductions); нахождение префикс-сумм массива (Prefix-Sums); алгоритмы изменения порядка (Reordering); алгоритмы сортировки (Sorting).
2 Примеры использования технологии CUDA
Для демонстрации преимущества технологии
CUDA были написаны несколько программ, в которых данная технология сравнивалась с подобной технологией MPI [4].
Приведем характеристики систем, на которых выполнялись вычислительные эксперименты:
1) персональный компьютер:
a) процессор Intel Core i5-3570K, 3.4 ГГц, 8 Гб ОЗУ ОС Linux Mint;
b) видеокарта NVIDIA GeForce GTX 650 TI c 2 Гб выделенной видеопамяти;
2) ноутбук:
a) процессор Intel Core i5-4210U, 1.7 ГГц, 6 Гб ОЗУ, ОС Ubuntu;
b) видеокарта NVIDIA GeForce 840M c 2 Гб выделенной видеопамяти.
2.1 Произведение матрицы на вектор
Для эффективности вычисления используется разделяемая память, так как разделяемая память расположена в мультипроцессорах. Также для удобства и быстроты вычислений используется двумерная матрица сетки блоков, и двумерная матрица нитей блоков, так как одним из множителей является матрица. Напомним алгоритм работы с технологией CUDA:
1 Выделение памяти;
2 Копирование данных из памяти, расположенной в CPU, в память, расположенной в GPU;
3 Осуществление запуска ядер-функций;
4 Копирование результатов из памяти GPU в память CPU;
5 Освобождение памяти в GPU.
Здесь и далее будем описывать каждый из этих пунктов.
1 Выделение памяти. double *d_A, *d_B, *d_C;
cudaMalloc ((void **) &d_A, dimsA.x * dimsA.y * sizeof(double)); cudaMalloc ((void **) &d_B, dimsB.x * dimsB.y * sizeof(double)); cudaMalloc ((void **) &d_C, dimsC.x * dimsC.y * sizeof(double));
Функция cudaMalloc принимает два параметра: 1 - указатель на указатель места памяти, где выделяется память, 2 - количество байт, выделяемое для хранения данных.
2 Копирование данных из памяти CPU в память GPU
cudaMemcpy (d_A, h_A, dimsA.x * dimsA.y * sizeof(double), cudaMemcpyHostToDevice); cudaMemcpy (d_B, h_B, dimsB.x * dimsB.y * sizeof(double), cudaMemcpyHostToDevice);
Функция cudaMemcpy принимает четыре параметра: 1 - приемник, 2 - источник, 3 - количество копируемых байт, 4 - константа. В данном случае это константа cudaMemcpyHostToDevice, так как нужно скопировать с CPU на GPU.
3 Осуществление запуска ядер-функций.
matrixVectorMulCUDA<<< grid, threads >>>(d_A, d_B, d_C, dimsA.x, dimsB.x);
Данное ядро принимает четыре параметра: 1 - матрица, 2 - вектор, 3 - размерность матрицы, 4 - размерность вектора.
4 Копирование результатов из памяти GPU в память CPU.
cudaMemcpy (h_C, d_C, dimsC.x * dimsC.y * sizeof(double), cudaMemcpyDeviceToHost);
Для копирования из памяти GPU в CPU используется также функция cudaMalloc, которая отличается от рассмотренной только четвертым параметром. Его значение должно быть равно cudaMemcpyDeviceToHost.
5 Освобождение памяти в GPU. cudaFree (d_A);
cudaFree (d_B); cudaFree (d_C); cudaDeviceReset ();
Функция cudaFree принимает один параметр: указатель на место памяти, которое нужно освободить. Ниже приведем реализацию ядра. const int BLOCK_SIZE = 16;
_global_void matrixVectorMulCUDA(double *A, double *B, double *C, int wA, int wB) {
int bx = blockIdx.x; nt by = blockIdx.y;
int tx = threadldx.x; int ty = threadldx.y;
int aBegin = wA * BLOCK_SIZE * by; int aEnd = aBegin + wA - 1; int aStep = BLOCK_SIZE;
int bBegin = BLOCK_SIZE * bx; int bStep = BLOCK_SIZE * wB;
double Csub = 0;
for (int a = aBegin, b = bBegin; a <= aEnd; a += aStep, b += bStep) {
_shared_double As[BLOCK_SIZE][BLOCK_SIZE];
_shared_double Bs[BLOCK_SIZE][BLOCK_SIZE];
As[ty][tx] = A[a + wA * ty + tx]; Bs[ty][tx] = B[b + wB * ty + tx];
_syncthreads();
for (int k = 0; k < BLOCK_SIZE; ++k) {
Csub += As[ty][k] * Bs[k][tx];
}
_syncthreads();
}
int c = wB * BLOCK_SIZE * by + BLOCK_SIZE * bx;
C[c + wB * ty + tx] = Csub;
}
Стоит заметить, что после копирования в разделяемую память следует производить синхронизацию нитей для дальнейших расчетов, так как, возможно, не все нити успели произвести копирование в разделяемую память.
Заметим, что данная операция уже реализована в CUDA, и она расположена в библиотеке cuBLAS.
Такой операции соответствует функция cublasDgemv. Перед тем, как использовать эту функцию, нужно также выделить память на устройстве, но требуется создать так называемый handle. Он нужен для того, чтобы мы могли использовать данную функцию для конкретного устройства. Для каждого устройства нужно создавать свой handle.
Эту операцию можно выполнить с помощью функции cublasCreate (&handle), которая принимает один параметр типа cublasHandle_t *.
Для удаления handle нужно использовать функцию cublasDestroy (handle), которая принимает один параметр типа cublasHandle_t.
Для копирования значений в память устройства, используют специальные функции. Приведем некото-
рые из них.
cublasSetMatrix (n, n, sizeof(*mA), mA, n, dev_mA, n);
cublasSetVector (n, sizeof(*V), V, 1, dev_V, 1);
Аналогично для получения значений также используют специальную функцию
cublasGetVector(n, sizeof(*Result), dev_Result, 1, Result, 1).
Приведем результаты времени выполнения созданных приложений (в миллисекундах) (рисунки 1 и 2).
2.2 Нахождение всех кратчайших путей в графе
Напомним последовательный алгоритм (алгоритм Флойда) для поиска всех кратчайших путей графа.
Ключевая идея алгоритма - разбиение процесса поиска кратчайших путей на фазы.
Перед k-й фазой величина d[i][j] равна длине кратчайшего пути из вершины i в вершину j, если этому пути разрешается заходить только в вершины с номерами, меньшими k (начало и конец пути не считаются). Заметим, что перед первой фазой матрица d[i][j] содержит исходную матрицу смежности. Если в графе не существует ребра из i в j, то в d[i][j] нужно записать «бесконечность» - число, которое будет больше возможного расстояния между этими вершинами. Для значений, стоящих на главной диагонали матрицы, d[i][j] следует записать 0.
На k-й фазе нужно производить пересчет матрицы d[i][j] следующим образом. Зафиксируем вершины i и j. Тогда кратчайший путь между вершинами i и j либо уже найден, т.е. проходит только через вершины с номерами от 1 до k-1, и тогда значение d[i][j] следует оставить без изменения, либо кратчайший путь будет проходить
Размер матрицы Без использования cuEHas С использованием cuBlas С использованием MPI
16 0.02630 0.02570 0.05174
32 0.01869 0.02902 0.0395&
64 0.02208 0.02256 0.04983
128 0.03158 0.02362 0.14472
256 0.06512 0.03008 0.39959
512 0.18256 0.05776 1.03307
1024 0.86566 0.13014 3.11327
2048 2.72090 0.48381 21.78574
4096 10.69494 1.89677 38.44810
Рисунок 1 - Результаты вычислений произведения матрицы на вектор на персональном компьютере
Размер матрицы Без использования cuBlas С использованием cuBtas С использованием MPI
16 0.02043 0.02355 0,05698
32 0.02358 0.02355 0.05269
64 0.03072 0.02560 0.09918
128 0.04912 0.02768 0.18644
256 0.15254 0.03690 0.65088
512 0.54170 0.14840 2.20609
1024 2.14426 0.60931 6.42610
2048 8.26672 2.44019 20.91479
4096 33.01475 9.76691 76.23863
Рисунок 2 - Результаты вычислений произведения матрицы на вектор на ноутбуке
через вершинку k. В этом случае значение d[i][j] нужно обновить значением d[i][k]+d[k][j]. Из выше сказанного следует простая формула для подсчета всех d[i][j]: d[i][j] = min(d[i][j], d[i][k]+d[k][j]).
Приведем ниже реализацию данного алгоритма в технологии CUDA.
1 Выделение памяти.
int dev_n = n * n * sizeof(double); double *dev_Matrix;
cudaMalloc((void**) &dev_Matrix, dev_n);
2 Копирование данных из памяти CPU в память GPU cudaMemcpy(dev_Matrix, Matrix, dev_n, cudaMemcpyHostToDevice); 3. Осуществление запуска ядер-функций.
dim3 threads(BLOCKSIZE, BLOCKSIZE); dim3 grid(n/BLOCKSIZE, n/BLOCKSIZE); for(int k = 0; k < n; k++) {
Kernel<<<grid, threads>>>(dev_Matrix, k, n);
}
Для того, чтобы ядро посчитало все кратчайшие пути, его нужно запускать для каждой вершины графа.
4 Копирование результатов из памяти GPU в память CPU. cudaMemcpy(Matrix, dev_Matrix, dev_n, cudaMemcpyDeviceToHost);
5 Освобождение памяти в GPU. cudaFree(dev_Matrix); cudaDeviceReset();
Ниже приведем реализацию ядра. const int BLOCKSIZE = 16; const double INF=1e9;
void_global_Kernel(double *Matrix, int k, int n){
int i = blockIdx.y * BLOCKSIZE + threadldx.y; int j = blockIdx.x * BLOCKSIZE + threadIdx.x;
if (i < n && j < n && Matrix[i*n + k] < INF && Matrix[k*n + j] < INF){
Matrix[i*n+j] = min(Matrix[i*n + j], Matrix[i*n + k] + Matrix[k*n + j]); }
}
Приведем результаты времени выполнения созданных приложений (в миллисекундах) (рисунки 3 и 4).
В процессе исследования было разработано четыре пары приложений (с использованием технологий CUDA и MPI), при выполнении которых сравнивалась их скорость работы. Были реализованы задачи умножения матрицы на вектор, умножения матриц, задача решения систем линейных алгебраических уравнений и задача нахождения всех кратчайших расстояний в графе.
По результатам оценивания скорости выполнения указанных пар приложений был сделан вывод: при возрастании размеров входных данных у приложений, созданных с использованием технологии CUDA, скорость расчетов значительно больше, чем у приложений, разработанных без использования данной технологии.
Размер матрицы С использованием CUDA С использованием MPI
16 0,37210 0.09608
32 0.39187 0.20456
64 0,25107 1.14012
128 0.95837 6.84714
256 5.46179 45.51291
512 33.70794 333.19068
1024 300.52682 2648.14806
2048 2419,73120 21260.57410
4096 19229,18555 168042.09328
Рисунок 3 - Результаты нахождения всех кратчайших расстояний в графе на персональном компьютере
Размер матрицы С использованием CUDA С использованием MPI
0.10550 0.16093
32 0.13122 0.49400
64 0.41165 1,73354
128 1.41309 14.24313
256 7.23664 93.59074
512 1 58.73009 736.77707
1024 1270.53723 6060.11748
2048 10178.60645 47035.64405
4096 81360.33594 37391 1,92198
Рисунок 4 - Результаты нахождения всех кратчайших расстояний в графе на ноутбуке
eliminates interference elements coaxial conductors with currents, does not provide for the existence of moments of forces acting on the elements of the conductors, Ampere's law is considered to be the formula generally incompatible with its main findings. The formal model is an analogue of the electromagnetic field, not having these features in this model meets the essential requirements Ampere -unconditional implementation of Newton's third law.
Keywords: magnetic field, Newton's third law, the elements of coaxial conductors, the moments of forces.
Список литературы
1 Сандерс Дж., Кэндрот Э. Технология CUDA в примерах: введение в программирование графических процессов / пер. с англ. А. А. Слинкина; научный редактор А. В. Боресков. М. : ДМК Пресс, 2013. 32 с.
2 Боресков А. В., Харламов А. А. Основы работы с технологией CUDA. М. : ДМК Пресс, 2013. 232 с.
3 Cuda Toolkit Documentation. URL: http://docs.nvidia.com/ cuda/#axzz3KAeRpjmq (дата обращения: 20.12.2015).
4 Козлов С. О. Технология CUDA. URL: http://it.kgsu.ru/C_ CUDA/oglav.html (дата обращения: 20.12.2015).
УДК 537.611 И.П. Попов
Курганская государственная сельскохозяйственная академия им. Т.С. Мальцева
ПОСТРОЕНИЕ МОДЕЛИ КВАЗИЭЛЕКТРОМАГНИТНОГО ПОЛЯ. ЧАСТЬ 1
Аннотация. Показано, что классическая модель магнитного поля допускает нарушение третьего закона Ньютона, исключает взаимодействие соосных элементов проводников с токами, не предусматривает существование моментов сил, действующих на элементы проводников, законом Ампера принято считать формулу, в общем случае несовместимую с его основным результатом. Построена формальная модель аналога электромагнитного поля, не имеющая указанных особенностей, при этом модель удовлетворяет основному требованию Ампера - безусловному выполнению третьего закона Ньютона.
Ключевые слова: магнитное поле, третий закон Ньютона, соосные элементы проводников, моменты сил.
I.P. Popov
Kurgan State Agricultural Academy. TS Maltsev
MODEL BUILDING QUASI-ELECTROMAGNETIC FIELD. PART 1
Annotation. It is shown that the classical model of the magnetic field allows the violation of Newton's third law,
ВВЕДЕНИЕ
Существующая модель магнитного поля допускает нарушение третьего закона Ньютона (ТЗН). На рисунке 1 представлен предельный случай такого нарушения.
I
I
d\l
dL
Рисунок 1 - Нарушение ТЗН
Первый элемент проводника СИ1 с током / действует на второй с силой
^ = 12 [[, б®; [Л 2 ,Г ]] , (1)
где с№1 - магнитная индукция, - магнитная проницаемость, г - радиус-вектор.
Эта сила имеет максимальное значение, поскольку все перемножаемые векторы взаимно перпендикулярны. В то же время второй элемент действует на первый с силой
^2 = I; [[ ^2 ] = ^ПГ [Л1 [ ,Г]] = 0,
так как и г коаксиальны.
Модель магнитного поля имеет ряд других противоречий, которые будут показаны ниже.
Целью настоящей работы является не исправление существующей теории электромагнитного поля [1-9], а построение в трехмерном евклидовом пространстве