\section{Introduction}
\label{sec:intro}

The problem of 2D DOA estimation, as an instantiation of multivariate spectral analysis, arises in many applications such as azimuth-elevation angle estimation using 2D arrays and transceiver design in MIMO communications. Despite of the large body of literature \cite{hlv}, existing techniques can be quite complex for implementation in emerging large-scale antenna systems such as massive MIMO, where super-resolution 2D angle estimation need to be performed with low computing time from a small number of measurements.

Subspace methods such as MUSIC and ESPRIT are popular for super-resolution 2D DOA estimation \cite{haardt19952d, roy1989esprit, hua1993pencil}. However, they all hinge on the sample covariance, which requires the number of snapshots to be larger than the antenna size. Besides, they are sensitive to signal correlation and noise, and may fail for coherent sources \cite{hlv}.

Advances in compressed sensing (CS) suggests to exploit source sparsity for frequency or angular estimation \cite{donoho2006, candes2006stable}. CS enables DOA estimation even from a single snapshot of  measurements, regardless of source correlation. However, the angular estimates are confined on a finite-resolution grid, and the accuracy is sensitive to off-grid source mismatch \cite{chi2011sensitivity}.

Recently, a new line of gridless CS for spectral analysis is developed via atomic norm minimization (ANM) in the form of semi-definite programming (SDP) \cite{tang2013compressed, candes2014towards}. It is a structure-based optimization approach where the Vandermonde structure of the array manifold is captured in the SDP via a Toeplitz matrix. It has been extended to the 2D case by exploiting  a two-level Toeplitz structure \cite{chi2015compressive, yang2016vandermonde}, which enjoys the benefits of the ANM approach in terms of  super-resolution from single-snapshot measurements, and resilience to source correlation.
However, the computational load is heavy, which becomes near intractable for large-scale antenna systems.

This paper presents a new formulation of ANM by introducing a new atom set that naturally decouples a two-level Toeplitz matrix into two Toeplitz matrices in one dimension. Accordingly, a new SDP formulation is developed for the decoupled ANM (D-ANM), which has a much reduced problem size and hence markedly improved computational efficiency. The time complexity is several orders of magnitude lower than that based on two-level Toeplitz, while other benefits of ANM  are preserved in terms of accuracy, resolution and use of a small number of snapshots. Analytic proof and simulations are presented in the paper to validate the proposed D-ANM  for low-complexity 2D DOA estimation.

\section{RELATION TO PRIOR WORK}
\label{sec:rel}

\vspace{-0.05in}
This work belongs to the ANM-based optimization approach to spectral estimation \cite{candes2014towards, tang2013compressed, bhaskar2013atomic, yang2015gridless}, which has emerged as an effective alternative to traditional statistics-based approaches when the number of measurements is small. While SDP formulations for ANM are mostly done for 1D spectral estimation, this work is closely related to the recent 2D results in \cite{chi2015compressive, yang2016vandermonde}. Therein, the 2D array manifold matrix is vectorized into a long vector, whose structure is expressed in a SDP formula through a two-level Toeplitz matrix, followed by two-level Vandermonde decomposition.  For an $N\times M$ rectangular antenna array, the size of the SDP is $(NM+1)$ \cite{chi2015compressive, yang2016vandermonde}. This work presents a new SDP formula for decoupled ANM (D-ANM) with a small size of $(N+M)$, which drastically reduces the run time. The D-ANM not only avoids the cumbersome vectorization step in \cite{chi2015compressive, yang2016vandermonde}, but also enables the use of simple one-level Vandermonde decomposition and automatic angle pairing. Hence, both the SDP formulation for ANM and the ensuing Vandermonde decomposition for 2D DOA estimation are different from those in \cite{chi2015compressive, yang2016vandermonde}.

\section{Signal Model}
\label{sec:bak}

Consider $K$ far-field narrowband waveforms $\mathbf{s}^\star=(s_1^\star, \dots, s_K^\star)^\mathrm{T}$ that impinge on an $N\times M$ uniform rectangular array with $N$ and $M$ elements along $x$-direction and $y$-direction respectively. The corresponding DOAs are denoted by $\boldsymbol{\theta}_x^\star=(\theta_{x, 1}^\star, \dots, \theta_{x, K}^\star)$ and $\boldsymbol{\theta}_y^\star=(\theta_{y, 1}^\star, \dots, \theta_{y, K}^\star)$ respectively. The noise-free baseband model for the array output matrix is
\begin{equation}
\label{eq:2.1}
\mathbf{X}(t) = \sum_{k=1}^{K} s_k^\star(t) \mathbf{a}_N(\theta_{x, k}^\star)\mathbf{a}_M^\mathrm{H}(\theta_{y, k}^\star)
\end{equation}
where $\mathbf{a}_N(\theta_x)$ of length $N$ is the 1D array response vector in $x$-direction with a Vandemonde structure along $\theta_x$ \cite{hlv}, and $\mathbf{a}_M(\theta_y)$ of length $M$ is similarly defined.

For clear exposition, we consider a single snapshot, thus dropping time $t$. Letting $\mathbf{A}_N(\boldsymbol{\theta}_x^\star)=[\mathbf{a}_N(\theta_{x, 1}^\star), \dots, \mathbf{a}_N(\theta_{x, K}^\star)]$, $\mathbf{A}_M(\boldsymbol{\theta}_y^\star)=[\mathbf{a}_M(\theta_{y, 1}^\star), \dots, \mathbf{a}_M(\theta_{y, K}^\star)]$, and $\mathbf{S}^\star=\mathrm{diag}(\mathbf{s}^\star)$, (\ref{eq:2.1}) can be concisely written as
\begin{equation}
	\label{eq:2.4}
	\mathbf{X}=\mathbf{A}_N(\boldsymbol{\theta}_x^\star)\mathbf{S}^\star\mathbf{A}_M^\mathrm{H}(\boldsymbol{\theta}_y^\star).
\end{equation}
The goal of 2D DOA estimation is to recover $\boldsymbol{\theta}_x^\star$ and $\boldsymbol{\theta}_y^\star$ from observations of $\mathbf{X}$.  Here we focus on the noise-free signal structure to formulate an optimization approach.

\section{The Atomic Norm Approach}

This section reviews the atomic norm minimization (ANM) approach to 2D DOA estimation in \cite{chi2015compressive, yang2016vandermonde}.
Using the Kronecker product $\otimes$,  the signal $\mathbf{X}$ can be vectorized as \cite{chi2015compressive}
\begin{equation}
	\label{eq:2.5}
		\mathbf{x}=\mathrm{vec}(\mathbf{X})=\sum_{k=1}^{K} s_k^\star \mathbf{a}_M^\ast({\theta}_{y, k}^\star)\otimes\mathbf{a}_N({\theta}_{x, k}^\star)=\sum_{k=1}^{K} s_k \mathbf{a}(\boldsymbol{\theta}_k^\star)
\end{equation}
where $\boldsymbol{\theta}=(\theta_{x}, \theta_{y})$, and $\mathbf{a}(\boldsymbol{\theta})=\mathbf{a}_M^\ast({\theta}_{y})\otimes\mathbf{a}_N(\theta_{x})$ is an extended array response vector of length $NM$.

The atom set $\mathcal{A}_V$ is defined as
\begin{equation}
\label{eq:2.atom}
	\mathcal{A}_V=\{\mathbf{a}(\boldsymbol{\theta}), \quad \boldsymbol{\theta}\in[0, 2\pi]\times[0, 2\pi]\}.
\end{equation}

Let  $\mathbf{T}_\mathrm{2D}(\mathbf{u})$, defined by its first row $\mathbf{u}$ of length $NM$, denote a  two-level Hermitian Toeplitz matrix constructed from the two-level Vandemonde structure of $\mathbf{a}(\boldsymbol{\theta})$  \cite{chi2015compressive}.
Then the atomic norm of $\mathbf{x}$ can be calculated via SDP:
\begin{eqnarray}
			\|\mathbf{x}\|_{\mathcal{A}_V}&\hspace{-0.08in}=&\hspace{-0.08in}\inf \left\{\sum_k |s_k| \left| \mathbf{x}=\sum_k s_k \mathbf{a}(\boldsymbol{\theta}_k), \ \ \mathbf{a}(\boldsymbol{\theta})\in\mathcal{A}_V \!\! \right. \right\} \nonumber \\
			&\hspace{-0.08in}=&\hspace{-0.08in}\min_{\mathbf{u}, v} \ \left\{\frac{1}{2}\left(v+\mathrm{trace}\big(\mathbf{T}_\mathrm{2D}(\mathbf{u})\big)\right)\right\} \nonumber \\
			&& \mathrm{s.t.}\quad \left(\begin{array}{cc}
			v & \mathbf{x}^\mathrm{H} \\
			\mathbf{x} & \mathbf{T}_\mathrm{2D}(\mathbf{u})
			\end{array}\right)\succeq \mathbf{0}. \label{eq:2.6}
\end{eqnarray}

It has been shown  that if $\mathbf{x}$ is composed of only a few adequately-separated sources, then $(\boldsymbol{\theta}_x^\star, \boldsymbol{\theta}_y^\star)$ can be recovered by computing $\|\mathbf{x}\|_{\mathcal{A}_V}$ from (noiseless, noisy or partial) observations of $\mathbf{x}$ \cite{chi2015compressive}. The SDP in (\ref{eq:2.6}) results in the two-level Toeplitz matrix $\mathbf{T}_\mathrm{2D}(\mathbf{u})$, which contains the angular information from both dimensions and can be processed via two-level Vandemonde decomposition to yield $(\boldsymbol{\theta}_x^\star, \boldsymbol{\theta}_y^\star)$  \cite{yang2016vandermonde}.

The main issue of the vectorization-based ANM in (\ref{eq:2.6}) is its high complexity. Due to the vectorization in (\ref{eq:2.5}), the matrix size in the SDP constraint is $(NM+1) \times (NM+1)$, which incurs high complexity in both computation and memory as $N$ and $M$ become large. We tried simulations on a PC for $N=M=32$, in which case the SDP calculation could not finish in two days. For large-scale antenna systems, an efficient implementation of the ANM principle is motivated.

\section{2D DOA estimation via Decoupled ANM}
\label{sec:main}

This section presents the main results, namely a decoupled ANM formulation for efficient 2D DOA estimation.

\subsection{Decoupled ANM and its SDP reformulation}

Recall the signal model  in (\ref{eq:2.1}) and (\ref{eq:2.4}). Alternative to the vectorized atom set in (\ref{eq:2.atom}), we adopt a new atom set $\mathcal{A}_M$ as
\begin{equation}
	\label{eq:3.1}
	\begin{split}
		\mathcal{A}_M&=\left\{\mathbf{a}_N(\theta_x)\mathbf{a}_M^\mathrm{H}(\theta_y), \quad \theta_x\in[0, 2\pi], \theta_y\in[0, 2\pi]\right\} \\
			&=\left\{\mathbf{A}(\boldsymbol{\theta}), \quad \boldsymbol{\theta}\in[0, 2\pi]\times[0, 2\pi]\right\}.
	\end{split}
\end{equation}

Our approach to find $(\boldsymbol{\theta}_x^\star, \boldsymbol{\theta}_y^\star)$ from $\mathbf{X}$ is to find the following atomic norm:
\begin{equation}
	\label{eq:3.2}
 \|\mathbf{X}\|_{\mathcal{A}_M}\!=\inf \left\{\!\sum_k |s_k| \left| \mathbf{X}=\!\sum_k s_k \mathbf{A}(\boldsymbol{\theta}_k), \ \ \mathbf{A}(\boldsymbol{\theta})\in\mathcal{A}_M \!\! \right. \right\}.
\end{equation}

This is an infinite programming problem over all feasible $\boldsymbol{\theta}$.
By reformulating (\ref{eq:3.2}) via SDP, our main results follow.

\begin{theorem}
	\label{th:1}
	Consider an $N\times M$ data matrix $\mathbf{X}$ given by
	\begin{equation}
		\label{eq:u2}
		\mathbf{X}=\textstyle \sum_{k=1}^{K} s_k^\star \mathbf{A}(\boldsymbol{\theta}_k^\star).
	\end{equation}
Define the minimal angle distances as $\Delta_{\min, x}=\min_{i\neq j} |\sin \theta_{x, i}^\star-\sin \theta_{x, j}^\star|$ and $\Delta_{\min, y}=\min_{i\neq j} |\sin \theta_{y, i}^\star-\sin \theta_{y, j}^\star|$,
which are wrapped distances on the unit circle. If they satisfy
	\begin{equation}
		\Delta_{\min, x}\geq\frac{1.19}{\lfloor(N-1)/4\rfloor}, \mathrm{~~~}\Delta_{\min, y}\geq\frac{1.19}{\lfloor(M-1)/4\rfloor},
	\end{equation}
then it is guaranteed that (\ref{eq:u2}) is the optimal solution to (\ref{eq:3.2}). Further, it can be efficiently computed via the following SDP:
	\begin{eqnarray}
		\|\mathbf{X}\|_{\mathcal{A}_M}&\hspace{-0.15in}=&\hspace{-0.15in}\min_{\mathbf{u}_x, \mathbf{u}_y}\! \!\left\{\! \frac{1}{2\sqrt{NM}}\bigg(\!\mathrm{trace}\big(\mathbf{T}(\mathbf{u}_x)\big)\!+\!\mathrm{trace}\big(\mathbf{T}(\mathbf{u}_y)\big)\!\!\bigg)\!\right\} \nonumber \\
		&&\mathrm{s.t.}\quad \left(\begin{array}{cc}
		\mathbf{T}(\mathbf{u}_y) & \mathbf{X}^\mathrm{H} \\
		\mathbf{X} & \mathbf{T}(\mathbf{u}_x)
		\end{array}\right)\succeq \mathbf{0}\label{eq:3.3}
	\end{eqnarray}
	where $\mathbf{T}(\mathbf{u}_x)$ and $\mathbf{T}(\mathbf{u}_y)$ are one-level Hermitian Toeplitz matrices defined by the first rows $\mathbf{u}_x$ and $\mathbf{u}_y$ respectively.
\end{theorem}

\noindent {\bf \em Remark 1: Angular information.} At the optimal $\hat{\mathbf{u}}_x$, the $N\times N$ Toeplitz matrix $\mathbf{T}(\hat{\mathbf{u}}_x)$ reveals $\boldsymbol{\theta}_x^\star$ via
\begin{equation} \label{eq:Tx}
\mathbf{T}(\hat{\mathbf{u}}_x)=\mathbf{A}_N(\boldsymbol{\theta}_x^\star) \mathbf{D}_x \mathbf{A}_N^{\mathrm{H}}(\boldsymbol{\theta}_x^\star), \quad \mathbf{D}_x \succeq \mathbf{0} \mathrm{~is~diagonal}.
 \end{equation}
Similarly,  $\boldsymbol{\theta}_y^\star$ is  coded in the $M\times M$ matrix $\mathbf{T}(\hat{\mathbf{u}}_y)$.
Hence, after the SDP in (\ref{eq:3.3}), 2D DOA information can be acquired via Vandemonde decomposition on these one-level Toeplitz matrices, which is much simpler than the two-level Vandemonde decomposition needed in \cite{chi2015compressive, yang2016vandermonde}, and there are many mature techniques such as
subspace methods, matrix pencil \cite{yang2016vandermonde} and Prony's method \cite{yang2015gridless}.

\noindent{\bf \em Remark 2: Decoupling.} The main benefit of the new result (\ref{eq:3.3}) is its low complexity via a decoupled formulation for ANM.  Instead of coupling the 2D DOA  via vectorization to form a constraint of size $(NM+1)\times (NM+1)$ in (\ref{eq:2.6}), (\ref{eq:3.3}) decouples the angular information into two one-level Toeplitz matrices, which markedly reduces the constraint size in SDP to $(N+M)\times(N+M)$.

\subsection{Sketch of proof}
\label{sec:prf}

The proof for Theorem \ref{th:1} will be detailed in a journal version. It is outlined next under the page limit.

\subsubsection{Uniqueness of atomic norm via dual polynomial}

Define the dual norm of $\|\cdot\|_{\mathcal{A}_M}$ for $\forall\mathbf{Q}\in\mathbb{C}^{N\times M}$ as
\begin{equation}
	\|\mathbf{Q}\|_{\mathcal{A}_M}^\ast=\sup_{\|\mathbf{X}\|_{\mathcal{A}_M}\leq 1} \langle\mathbf{Q}, \mathbf{X}\rangle_\mathcal{R}
\end{equation}
where $\langle\cdot, \cdot\rangle$ denotes the Frobenius inner product, and $\langle\cdot, \cdot\rangle_\mathcal{R}=\Re\left\{\langle\cdot, \cdot\rangle\right\}$ keeps the real part.

Following standard Lagrangian analysis as in \cite{tang2013compressed, boyd2004convex},
one can show that if there exists a dual polynomial
\begin{equation}
	Q(\boldsymbol{\theta}) =\langle \mathbf{Q}, \mathbf{A}(\boldsymbol{\theta})\rangle, \quad  \mathbf{Q}\in\mathbb{C}^{N\times M}, \ \mathbf{A}(\boldsymbol{\theta})\in\mathcal{A}_M
\end{equation}
satisfying the conditions (bounded interpolation property)
	\begin{equation}
	\label{eq:c1+2}
\begin{split}
		Q(\boldsymbol{\theta}_k^\star)&=\mathrm{sign}(s_k^\star), \quad \forall \boldsymbol{\theta}_k^\star\in\Omega;
\\
		|Q(\boldsymbol{\theta})|&<1, \quad \quad \quad \quad \forall \boldsymbol{\theta}\notin\Omega,
\end{split}
	\end{equation}
then it is guaranteed that the optimal solution to (\ref{eq:3.2}) is unique, where $\Omega=\{\boldsymbol{\theta}_1^\star, \dots, \boldsymbol{\theta}_K^\star\}$ collects all supports of $\mathbf{X}$.

The rest of proof is to find a dual polynomial that satisfies the above conditions, following a similar procedure as in \cite{chi2015compressive}.

\subsubsection{Equivalence of atomic norm to SDP with decoupling}

Denote the optimal solution of (\ref{eq:3.3}) as $\mathrm{SDP}(\mathbf{X})$. On one hand, for arbitrary atomic decomposition of $\mathbf{X}=\sum_k s_k \mathbf{A}(\boldsymbol{\theta}_k)$, it is easy to verify the semi-definite contraint in (\ref{eq:3.3}) by letting $\mathbf{T}(\mathbf{u}_x)=\sum_k |s_k| \sqrt{\frac{M}{N}}   \mathbf{a}_N(\theta_{x, k}) \mathbf{a}_N^\mathrm{H}(\theta_{x, k})$ and $\mathbf{T}(\mathbf{u}_y)=\sum_k |s_k| \sqrt{\frac{N}{M}} \mathbf{a}_M(\theta_{y, k}) \mathbf{a}_M^\mathrm{H}(\theta_{y, k})$; hence, $\mathrm{SDP}(\mathbf{X})\leq\|\mathbf{X}\|_{\mathcal{A}_M}$.

On the other hand, from the semi-definite condition, $\mathbf{X}$ lies in the column space of $\mathbf{T}(\mathbf{u}_x)$ and row space of $\mathbf{T}(\mathbf{u}_y)$. Similar to \cite{yang2014exact}, using Schur completion lemma and geometry averaging inequality, one can verify $\mathrm{SDP}(\mathbf{X})\geq\|\mathbf{X}\|_{\mathcal{A}_M}$.

\subsection{2D DOA Estimation based on decoupled ANM}

In practice, $\mathbf{X}$ is observed implicitly. We consider a linear observation model in the presence of an additive noise $\mathbf{W}$:
\begin{equation}
\label{eq:5.3.1}
	\mathbf{Y}= \mathcal{L}(\mathbf{X}) + \mathbf{W}
\end{equation}
where $\mathcal{L}(\cdot)$ represents linear mixing, with possible missing entries and down-sampling. Given $\mathbf{Y}$, and exploiting the signal structure (\ref{eq:3.3}),  $\mathbf{X}$ can be estimated via regularization
\begin{equation}
	\min_\mathbf{X} \quad \lambda\|\mathbf{X}\|_{\mathcal{A}_M}+\|\mathbf{Y}-\mathcal{L}(\mathbf{X})\|_\mathrm{F}^2
\end{equation}
where $\lambda\geq 0$ is a weighting scalar. To find the 2D DOA, it is adequate to find the two desired Toeplitz matrices via
\begin{equation}
		\label{eq:5.3.3}
		\begin{split}
		\min_{\mathbf{u}_x, \mathbf{u}_y, \mathbf{X}} &\quad \frac{\lambda}{2\sqrt{NM}}\bigg(\!\mathrm{trace}\big(\mathbf{T}(\mathbf{u}_x)\big)+\mathrm{trace}\big(\mathbf{T}(\mathbf{u}_y)\big)\!\!\bigg)  \\
		 & \quad +\|\mathbf{Y}-\mathcal{L}(\mathbf{X})\|_\mathrm{F}^2\\
		\mathrm{s.t.} & \quad \left(\begin{array}{cc}
		\mathbf{T}(\mathbf{u}_y) & \mathbf{X}^\mathrm{H} \\
		\mathbf{X} & \mathbf{T}(\mathbf{u}_x)
		\end{array}\right)\succeq \mathbf{0}.
		\end{split}
	\end{equation}
As mentioned in {\bf \em Remark 1}, mature 1D DOA estimators can be employed to obtain the estimates $\hat{\boldsymbol{\theta}}_{x}$ and $\hat{\boldsymbol{\theta}}_y$ from the optimal  $\mathbf{T}(\hat{\mathbf{u}}_x)$ and $\mathbf{T}(\hat{\mathbf{u}}_y)$, in a decoupled manner.

Like all 2D DOA estimators, a  pairing step is critical to find $(\hat{\theta}_{x, k}, \hat{\theta}_{y, k})$ pairs, $\forall k$. Since we have $\hat{\mathbf{X}}$ at hand via (\ref{eq:5.3.3}), we develop a simple angle pairing technique as follows.
\begin{enumerate}
\itemsep -0.03in
	\item Construct the array response matrix $\mathbf{A}_N(\hat{\boldsymbol{\theta}}_x)$ from $\hat{\boldsymbol{\theta}}_x$.
	\item Compute $\mathbf{V}_M=\mathbf{D}_x^{-1}\mathbf{A}_N^\dagger(\hat{\boldsymbol{\theta}}_x)\hat{\mathbf{X}}$, where $(\cdot)^\dagger$ denotes pseudo-inverse and $\mathbf{D}_x$ is the diagonal matrix in (\ref{eq:Tx}) obtained from Vandermonde decomposition of $\mathbf{T}(\hat{\mathbf{u}}_x)$. In the noise-free case, $\mathbf{V}_M^\mathrm{H} = [\mathbf{v}_1, \ldots, \mathbf{v}_K]$ is the same as $\mathbf{A}_M(\boldsymbol{\theta}_y^\star)$ up to phase ambiguity and global scaling.
	\item Pair up $\hat{\theta}_{y,k}$ with $\hat{\theta}_{x,k_y}$ via maximum correlation:
	\[ k_y = \arg \max_{j\in [1, K]}  \left| \left\langle \mathbf{a}_M(\hat{\theta}_{y,k}), \mathbf{v}_j \right \rangle \right|, \quad k = 1, \ldots, K. \]
\end{enumerate}

\section{Performance Evaluation}
\label{sec:sim}

\subsection{Complexity analysis}

As mentioned in {\bf Remark 2},
in the {\em  vectorized ANM} method \cite{chi2015compressive}, the semi-definite constraint in (\ref{eq:2.6}) is of size $(NM+1)\times(NM+1)$. As a result, the SDP step for recovering the two-level Toeplitz has time complexity $\mathcal{O}(N^{3.5}M^{3.5}\log(1/\epsilon))$, where $\epsilon$ is the desired recovery precision \cite{krishnan2005interior}; the ensuing step of two-level Vandermonde decomposition for angle estimation and pairing has time complexity $\mathcal{O}(N^2 M^2 K)$ \cite{yang2016vandermonde}.

In contrast, our {\em decoupled ANM} formulation in (\ref{eq:3.3}) and (\ref{eq:5.3.3}) has a constraint of smaller size $(N+M)\times(N+M)$. The time complexity of the SDP step is $\mathcal{O}((N+M)^{3.5}\log(1/\epsilon))$, and that of the one-level Vandermonde decomposition and pairing step is $\mathcal{O}((N^2 +M^2) K)$. The overall complexity is reduced by an order of $\mathcal{O}(N^{3.5})$ for $N=M$.

Simulations of the run time are performed for a square array with $M=N$, and $K=4$ sources. The running speeds of these two methods are plotted on a logarithmic scale versus $N$ in Figure \ref{fig:3}. Our method exhibits a huge benefit in computational efficiency for large-scale arrays. When $M=N=22$, the running time of the vectorized ANM is 733.1842s, while that of the decoupled ANM is only 1.4997s.

\begin{figure}[t]
	\centering
	\includegraphics[width=.93\columnwidth]{2.eps}
	\vspace{-0.1in}
	\caption{Computing complexity: run time versus $N$ ($N=M$).}
	\label{fig:3}
\end{figure}

\subsection{Recovery accuracy and noise performance}

Mont\`{e} Carlo simulations are carried out to evaluate the DOA estimation performance of both ANM-based 2D DOA methods, with $M=N=16$ and $K=4$.  Following SDP, the matrix pencil method is used to carry out both one- and two-level Vandermonde decomposition for DOA estimation \cite{yang2016vandermonde, hua1993pencil}.

Figure \ref{fig:1} depicts the estimated 2D angles at a high signal to noise ratio (SNR) of 20dB. All source angles are accurately recovered, which confirms that both ANM methods correctly capture the inherent signal structures in their formulations.

\begin{figure}[t]
	\centering
		\includegraphics[width=.93\columnwidth]{1.eps}
		\vspace{-0.1in}
	\caption{2D DOA (SNR = 20dB).}
	\label{fig:1}
\end{figure}

Figure \ref{fig:4} compares the average mean square error (MSE) of the estimates $\sin\boldsymbol{\hat{\theta}}$ versus SNR, with reference to the Cramer-Rao bound (CRB)  \cite{liu2007multidimensional}. The MSE performance of the proposed decoupled ANM is quite close to that of the vectorized ANM, both approaching the CRB for large SNR.

\begin{figure}[t]
	\centering
		\includegraphics[width=.93\columnwidth]{3.eps}
		\vspace{-0.1in}
	\caption{Noise performance: MSE vs. SNR ($N=M=16$).}
	\label{fig:4}
\end{figure}

\section{Conclusion}
\label{sec:con}

This work presents a novel decoupled ANM approach to 2D DOA estimation. By introducing a new atom set and decoupling the angular information onto lower dimension, we have reduced the computational load by several orders of magnitude in array size, while retaining the benefits of ANM in terms of gridless estimation, light  measurement requirements and robustness to signal correlation. Automatic angle pairing is also developed. The proposed low-complexity optimization technique can be extended to other high-dimensional spectral estimation problems as well. Future work includes performance analysis in the presence of data compression and noise.

\bibliographystyle{IEEEbib}


\section{Conclusion}
To identify the root causes of performance anomalies of kernel IO, \sys provides
fine-grained performance profiling of kernel IO stacks. \sys tags each IO request
with {\tt request ID} and traces the {\tt request ID} through IO layers, measuring
precise latency of each IO layer the IO request travels. \sys leverages existing
kernel instrumentation framework to dynamically install trace points and collects
latency information within 3 - 10\% overhead.

\section{Design and Implementation}

\begin{figure}
\center{\includegraphics[width=0.4\textwidth]
	{outline2.pdf}}
	\caption{\label{fig:outline} \textbf{\sys} Architecture.}
\end{figure}

The goal of \sys is to provide precise and fine-grained latency information of kernel IO subsystems
with minimal performance overhead.
\sys starts tracing on each system call and generates trace data profiling timing of
kernel IO layers. With the trace data, \sys computes fine-grained latency breakdown of each IO layer.
To minimize runtime overhead of a target system, \sys leverages an existing lightweight
instrumentation framework~\cite{kprobe,uprobe, tracepoints, ftrace,perf, ebpf, lttng,stap,dtrace}.
The number of trace points directly affects the runtime
overhead of a target system. Kernel instrumentation frameworks have the flexibility
to control the number of trace points, enabling \sys to manage the runtime overhead.
The remainder of this section describes the design of \sys by giving a case study
of the read system call.

\subsection{Architecture}
\sys comprises a front end and a back end system. Figure~\ref{fig:outline} shows
the overall architecture of \sys. The front end is planted to a target system
and collects tracing data, and the back end processes data obtained from the front end and visualizes them.

\begin{figure}
\center{\includegraphics[width=0.4\textwidth]
	{frontend.pdf}}
	\caption{\label{fig:frontend} Profile script describes probing points and probe handers. A probe
	handler generally consists of getting rid, collecting trace data to a log, and writing the log
	to the ring buffer.}
\end{figure}

\textbf{Leveraging instrumentation.} Modern operating systems support kernel dynamic instrumentation~\cite{lttng,ebpf,stap,dtrace,ftrace}.
A kernel dynamic instrumentation allows execution of user-defined code into in-memory kernel code
at function boundaries (i.e., entering and exiting a function) or in any lines (called {\it probe point}).
When a kernel execution hits an installed probe point, the instrumentation framework calls
a procedure (called {\it probe handler}) registered by the framework.
The front end takes advantage of existing kernel dynamic instrumentation frameworks to
install arbitrary probe points into a running kernel~\cite{kprobe, uprobe, tracepoints, ftrace, perf,stap}.
The front end takes a profile script to install probe points.
In Figure~\ref{fig:frontend}, we show an example of the profile script.
The profile script is written in a domain-specific language
describing probe points of each kernel layer as a list of kernel functions, entry and exit
actions defined as a probe handler, and hardware events~\cite{perf} to monitor.
The tracing framework compiles the profile script to a binary and inserts it
into kernel memory using a kernel dynamic instrumentation framework.

\subsection{Front end}

The primary goal of the front end install probe points and probe handlers
to collect timing information of each IO layer in each IO request.
The front end installs probe points in execution paths of the system call,
off-CPU events, and interrupt service routines.

\begin{figure}
\center{\includegraphics[width=0.45\textwidth]
	{RidCallChain.pdf}}
	\caption{\label{fig:RidCallChain} request id propagation through function calls.
	After the request is queued at the request layer, SCSI driver keeps checking the queue and handles the queued requests. }
\end{figure}

\noindent \textbf{Tracing system calls.}
Because the system call is the way of entering into the kernel space,
we first focus on how we trace system calls to get the {\it per-request} latency distribution.
An IO system call extends across multiple layers of kernel components.
For example, in Linux, a read system call travels through
VFS and page cache layer, file system layer, block IO layer, and device driver layer.
Each layer has different performance characteristics such as memory copy bandwidth or
slowdown by lock contentions. In addition to that, concurrent system calls make the analysis more complicated because
it is hard to distinguish what system call is executing without having
a complex function parameter analysis and matching thread id which causes
non-negligible overhead in IO-intensive workloads.

To provide lightweight and fine-grained tracing, \sys associates a {\it request id}
(or {\it rid}) with an IO system call to trace. {\tt rid} is a timestamp monotonically
increasing and serves as a unique identifier of an IO system call. To track
individual IO system calls across the layers, \sys propagates an assigned {\tt rid} for each read system call
to lower layers of the kernel as depicted in Figure~\ref{fig:RidCallChain}. The value of {\it rid} is initially stored
in {\tt struct file} (VFS layer), transferred to {\tt struct kiocb} (memory management layer)
and the subsequent layers. To implement the {\it rid} propagation, we slightly modify kernel data structures
to hold the {\it rid} and add code to maintain the {\it rid} value when a layer is switched.
We use a kernel instrumentation framework to change 29 lines of code in the Linux kernel for tracing read IO
(7 lines for {\it rid} in struct and 22 lines for {\it rid} propagation).
This minimizes performance and space overhead when tracing a large volume of IO requests.
\sys can work with any instrumentaion framework that supports on-the-fly
modification of kernel code.

\noindent \textbf{Tracing off-CPU events.} In addition to system calls, \sys supports profiling off-CPU events.
Some IO system calls execute their part of code paths on a different CPU,
which makes it hard to distinguish the origin of an IO request.
For example, read or write system calls make a block IO request
to a kernel IO thread and wait until the kernel IO thread completes the IO request.
The off-CPU execution path must be added to the total latency of the system calls.
To associate a system call and off-CPU execution, \sys transfers the {\it rid} to
off-CPU kernel functions.
Generally, there is a shared data structure for the off-CPU handler (e.g., {\tt struct bio}
and {\tt struct request} in Figure~\ref{fig:RidCallChain}).
\sys installs probe points on off-CPU kernel events to profile and
delivers {\it rid} to an off-CPU probe point via a data structure used for a parameter.

\noindent \textbf{Tracing kernel activities.} Tracing only execution paths of system calls
causes an inaccurate profile result because the kernel execution can be interrupted by
various external events. For example, an interrupt handling during a read
system call causes a delay in a layer. If probe points are installed at function boundaries
of a system call execution path, the delay would not be accounted.
To sort out the delay made by the kernel activities, \sys also installs probe points
on interrupt handling routines, schedule in and out handlers, and the wakeup points
of background kernel threads, recording occurences of the event and its timing
information.

\sys installs a probe handler, described in Figure~\ref{fig:frontend}, on each probe point.
A probe point can be either an entry and an exit of a function or both based on
profile description in Figure~\ref{fig:frontend}.
A probe handler creates a trace log consisting of {\tt <function name, process id, cpu id,
rid, timestamp, hardware events>} and records the log to a ring buffer. The ring buffer
is a protected, shared memory between kernel and user-level applications.
The ring buffer size is 4MB (1024 * 4KB page) by default. A \sys's
user-level agent in a target system periodically sends trace logs to the back end
via the network to avoid buffer overruns.

\subsection{Back end}
The goal of the back end is to compute {\it per-layer} latency breakdowns from
raw log records traced by the front end.
The back end aggregates the log records with a {\it request id} and then
invokes an analyzer for each {\it request id}.
Along with a profile description, the analyzer takes a layer description, which
specifies layer types and how to separate layers with given function names.
With the layer description, the analyzer computes {\it per-layer} latency of each
system call request which has the same {\it rid} in the log records. If a traced function, $f_1$,
calls a function, $f_2$, belonging to a lower layer, the analyzer subtracts the
time taken by $f_2$ when computing latency of $f_1$. The analyzer checks
whether an off-CPU event happens in the middle of execution of a traced function.
If an event happens, the analyzer separately accounts the latency caused by
the off-CPU event when computing latency of a traced function. In case that
a hardware event (e.g., CPI) is recorded in a traced function, the analyzer correlates the hardware event with
the traced function and records the hardware event data with a computed latency.
Finally, the analyzer stores the processed data to an intermediate format, and
the visualizer draws a figure, which can be rendered in web browsers.

\section{Evaluation}

In this section, we explore possible application scenarios of \sys to understand kernel behaviors at fine-grained level.
Our prototype leverages the {\tt ebpf} framework supported by standard Linux to make use of the tracing facility~\cite{ebpf}.
The target system consists of the Intel Xeon CPU E5-2695 v4 CPU, 128GB DDR4 memory, and 256GB SATA SSD.
We use a Ubuntu 16.04 machine with modified kernel version 4.15 and the ext4 filesystem.
We run various workloads of synchronous read I/O operations generated by FIO benchmark \cite{fio} on the target system
to observe the effectiveness of \sys in terms of the {\it per-request} and {\it per-layer} profiling facility.
First, we examine single-threaded sequential and random read access patterns, then we move on to the multi-threaded benchmark study.

\subsection{Read System Calls and Page Cache}
In general, when the Linux operating system receives a read request from a user, it first looks up
in the main memory cache, called \textit{page cache}, to check if the requested data is already in memory.
Based on this mechanism, we categorize the read system requests into
two classes - page cache hit and page cache miss.
In cases of page cache hits, the read requests are rapidly served without
traversing through multiple kernel layers.
On the other hand, read system calls that experience page cache misses are more time-consuming because
they go down to lower kernel layers to access the storage medium and
bring the requested page into the memory.

\begin{figure}[]
\centering
\includegraphics[width=0.5\textwidth]{irq.pdf}
\caption{{\it Per-request} latency (solid) and CPI (dotted) for single-threaded sequential read requests in chronological order.
  Only page cache hit cases are shown. Each latency is broken down into four kernel layers - {\tt vfs, mm, cpy, irq}}
\label{fig:latencyandCPI}
\end{figure}

\noindent {\bf Tail latency within page cache hits.}
We expect that the latency variation among read requests would not be significant if the requested data reside in the page cache.
Interestingly, however, \sys reports that latency still varies widely within page cache hit cases.
Figure~\ref{fig:latencyandCPI} shows {\it per-request} read system call latency (for page cache hits) when a file is read sequentially by a single thread.
The x-axis represents individual requests in chronological order.
For most requests, the latency is measured around 18000ns, but we observe that there are several noticeable spikes that rise above 25000ns.
To identify the cause of tail latencies, we additionally analyze the CPI
(cycles per instruction) provided by \sys front end for each request, which is depicted by the dotted line in the same figure.
As the latency fluctuates, the CPI follows the same trend.
Using the {\it per-layer} facility of \sys, we dissect the latency into four layers
 - virtual file system ({\tt vfs}), memory management ({\tt mm}), page copy ({\tt cpy}), and interrupt request handle ({\tt irq}).
The data visualization output by our tracer shows that the fluctuation does not occur in a particular layer,
but, instead, different components are responsible for slowdown in each request.
{\tt vfs} layer turns out to be the causative factor of tail \ding{202} and \ding{205}.
Similarly, {\tt cpy} layer was the bottleneck in tail \ding{203} and \ding{207}.
The layer breakdown utility shows us that tail \ding{204} additionally contains {\tt irq} layer.
In fact, the high latency in this particular request was due to a hardware interrupt for IO completion which occurred at {\tt mm} layer.
{\tt irq} not only adds an extra layer in the request
but also introduces huge context switch overhead in the interrupted layer.
\sys allows in-depth analysis to locate unusual latency spikes even within page cache hits
and further diagnose the root cause of each at hardware and software levels.

\begin{figure}[]
\centering
\includegraphics[width=0.4\textwidth]{LayerBreakdownSeparate.pdf}
\caption{{\it Per-layer} breakdown of latency for single-threaded random read requests in chronological order.}
\label{fig:per_layer}
\end{figure}

\noindent {\bf Tail latency within page cache misses.}
We also examine a scenario where the read system calls do not benefit from the page cache due to the random access pattern.
Figure~\ref{fig:per_layer} shows {\it per-layer} breakdown of request latency for single-threaded random reads on a file.
When read requests are made for random positions in a file, most requests experience page cache misses
and suffer much higher latency because they penetrate through deeper layers down to storage to bring data into memory.
A large portion of the time is spent in performing disk I/O, as depicted by the
thick green layer ({\tt io}) in Figure~\ref{fig:lat_breakdown}.
Figure~\ref{fig:per_layer} corresponds to the layer decomposition of requests in the spiking region (requests 3560 - 3600) of Figure~\ref{fig:lat_breakdown}.
By breaking each request down to units of a kernel layer,
it is possible to observe that each burst is caused by different layers
even within a small interval of 40 requests.
The largest three spikes (\textcircled{\raisebox{-0.8pt}{A}}) are due to delay in the Disk I/O layer,
but the smaller spikes that appear immediately before and after (\textcircled{\raisebox{-0.8pt}{B}}) are caused by
equally proportional slowdown in all other six layers.
Since the random read requests do not have access locality, we anticipate that there is no significant latency difference among them.
However, \sys informs us that multiple tail latencies can occur in a batched manner within a small time interval
and that different layers contribute to each tail.
\subsection{Profiling Multi-threaded Behaviors}

\begin{figure}[]
\centering
\includegraphics[width=0.5\textwidth]{FairnessBreakdown.pdf}
\caption{99th-percentile latency within each time interval for threads T1, T2, T3, T4
  simultaneously performing random read operations on a single file.
  Total 90,000 requests are divided into 15 intervals, each containing 6000
requests.}
\label{fig:FairnessBreakdown}
\end{figure}

In this subsection, we examine the {\it fairness} of issuing random read operations by multiple threads.
As each thread makes its read request, the requests end up mixed across the underlying kernel layers.
With its ability to measure the latency on a {\it per-request} basis, however, \sys is able to retrieve the owner thread of each request.
Figure~\ref{fig:FairnessBreakdown} shows 99th percentile latency of each thread over time with 6,000 requests as a group of the time interval ({\it window}), with
each bar representing individual threads.
From window 5 to 13, we observe that T1 and T3 experience much longer tail latency.
In fact, we identify that the burden of IRQ handling was unfairly distributed
throughout threads. Certain threads served much more IRQ requests than the others and had to spend up to
60x more time on IRQ handling as shown in Table~\ref{tab:irq_time}.

\begin{table}[]
\resizebox{\columnwidth}{!}{%
\begin{tabular}{c|r|r}
\toprule
Thread  & \# of IRQ handled &  Time spent on IRQ (ns) \\
\midrule
T1        & 7,276              & 47,849,914        \\
T2        & 128                & 816,828           \\
T3        & 2,953              & 19,398,496        \\
T4        & 121                & 787,582           \\
\bottomrule
\end{tabular}
}
\caption{Number of IRQ events handled by each thread and the total time spent on handling IRQ during execution.}
\label{tab:irq_time}
\end{table}

\subsection{Overhead}
We end the section by evaluating the performance overhead of \sys.
First, we measure the read throughput (bandwidth) for sequential read access patterns with 8 threads.
In this case, threads do not experience any throughput degradation when running with \sys.
Since most of the read operations are served by the page cache, the depth of IO path for most requests is small.
As a result, the overhead introduced by the additional CPU cycles from the
tracer is negligible.

Next, we measure the overhead of \sys for random read accesses by 8 threads.
Table~\ref{tab:overhead} shows the throughput overhead with increasing depth of probe layers.
As the probe depth increases, the number of probe points also increases.
For random accesses, the page cache does not help, so all possible tracing points across the 8 layers will be reached frequently,
resulting in non-negligible overhead.
At minimum depth ({\tt L1}), the bandwidth degradation is only 3\%, but it can increase up to 10.7\% with maximum depth ({\tt L8}).
This result depicts the tradeoff between the profiling depth and the
overhead.
In response to this, \sys provides a control knob to users to adjust the profiling granularity.

\begin{table}[]
\resizebox{\columnwidth}{!}{%
\begin{tabular}{l|cccccccc}
\toprule
Probe depth     & L1 & L2  & L3 & L4  & L5  & L6  & L7  & L8   \\ \hline
Overhead(\%) & 3  & 3.3 & 6  & 6.1 & 8.3 & 8.4 & 9.5 & 10.7 \\ \hline
\# Probe points  & 2  & 6   & 8  & 9   & 12   & 13   & 14   & 15    \\
\bottomrule
\end{tabular}%
}
\caption{Bandwidth degradation with increasing probe depth when tracing
8 threads simultaneously performing random read a total of 2GB of data.}
\label{tab:overhead}
\end{table}

\section{Introduction}

Understanding IO performance problems is challenging. Performance of kernel IO stacks
are affected by underlying hardware behaviors such as CPU cache locality~\cite{densefs,flexsc,Yang:2012}.
The hardware behaviors add an unexpected delay to kernel IO executions, causing
high performance variations and tail latency. Also, kernel IO executions are often
interrupted by internal kernel activities such as interrupts and exceptions or
scheduler preemptions, make it hard for developers to pinpoint the root cause
of an unexpected performance anomaly.

What makes the cases harder is that developers require fine-grained profiling information
from the complex kernel IO stack. Modern IO stack is built by a set of abstraction layers
each of which has different performance characteristics.
Developers want to profile the latency breakdown of each layer to identify performance bottlenecks.
Furthermore, they would like to know latency distributions of each IO request
to understand what request causes a tail latency and which layer causes the slowdown
comparing to other requests.

In response to the requirement of kernel IO profiling, there are many research and
practical tools to make an effort to provide useful information.
They provide latency breakdown of entire kernel IO stack or block layer but
do not give detailed latency distributions of individual requests~\cite{Joukov:2006, Traeger:2008,
Shin:2014, Xu:2015} and require massive kernel changes to collect trace data~\cite{Joukov:2006, Doray:2017, Ruan:2004}.

\begin{figure}
	\center
	\includegraphics[width=0.45\textwidth]
    {LayerBreakdown.pdf}
	\caption{Read latency breakdown of each layer. X-axis is read requests.}
	\label{fig:lat_breakdown}
\end{figure}

In this paper, we introduce a profiling tool for analyzing kernel IO performance in detail,
called \sys ({\tt per-\underline{Re}quest per-\underline{Lay}er} tracer).
\sys provides the latency distributions of each kernel request along with
fine-grained information such as {\it per-abstraction-layer} latency breakdown.
To that end, \sys maps each kernel request (e.g., system call)
to {\it request ID} and tracks the {\it request ID} across the abstraction layers.
By tagging each IO request with a {\it request ID}, which propagates across IO layers, \sys can
report a latency breakdown of each layer of an individual IO request.
Figure~\ref{fig:lat_breakdown} shows the latency breakdown of IO layers profiled by \sys.
Peaks show tail latency, and Figure~\ref{fig:lat_breakdown} shows where the latency peaks happen among
the seven layers. In Linux, a background kernel thread performs device IO asynchronously.
\sys traces the {\it off-CPU event} made by an IO request using the {\it request ID}.
To provide a precise latency breakdown, \sys analyzes an unexpected
delay made by internal kernel activities and accounts them separately.
Also, \sys monitors hardware performance behavior (e.g., IPC) along with a latency profile of each layer,
supporting reasoning about tail latency.

\sys adopts the split architecture consisting of a front end and a back end. The front end of \sys
runs with the target system to profile, collecting data with minimal runtime overhead.
The back end of \sys, working as separate processes, processes data collected by the front end and visualizes the
processed data with graphs. The front end of \sys leverages the dynamic instrumentation
framework~\cite{lttng,ebpf,dtrace,stap,ftrace}, supported in the most of modern operating systems, to
minimize profiling overheads ({\it low overhead}) by tracing only required execution points of interest.
With the dynamic instrumentation, \sys can
profile any kernel subsystems ({\it versatility}) and easily adapt kernel code changes ({\it portability}).
\sys provides fine-grained performance profiling with 3 - 10\% for random read, 0.1\% for sequential read runtime overhead.

This paper makes the following contributions:
\begin{compactitem}
\item By tracing each IO request with a {\it request ID}, \sys can trace per-layer latency on the path
of executing an individual IO request.
\item By monitoring internal kernel activities, \sys can separately account the interference caused the
kernel activities.
\item By bundling software and hardware performance information, \sys can precisely analyze the Linux
IO performance.
\end{compactitem}
The current scope of the work focuses on the read path of IO. Adding support for
other IO system calls is future work.